Einzelnen Beitrag anzeigen

quendolineDD

Registriert seit: 19. Apr 2007
Ort: Dresden
781 Beiträge
 
Turbo Delphi für Win32
 
#32

Re: Fehlermeldung "Element hat kein übergeördnetes Fens

  Alt 19. Feb 2009, 13:05
Deswegen könnte man ja einen Thread mitlaufen lassen, welcher alle neuen Berechnungen mitgeteilt bekommt. Der speichert die ab unnd gibt dann die Berechungen in angemessenen Zeitabständen an den Hauptthread weiter und trägt diese in allen Memos ein. Wenn du zB immer wartest bis alle 4 Threads berechnet haben, hast du nur noch einen Zugriff anstatt 4. Das würde schon mal den Hauptthread weniger belasten.

Da könnte die parallel mitlaufende Thread-Klasse ca. so aussehen:

Delphi-Quellcode:
unit Unit2;

interface

uses Classes, Windows;

type
  TSyncThread = Class(TThread)
    constructor Create;
    private
      FCalculates : TStringList;
      FThreadHandles : TWOHandleArray;
      FRegistredThreads : Integer;

      function GetNextFree : Integer;

    protected
      procedure Execute; override;

    public
      procedure AddCalc(ACalc : String);
      procedure RegisterThread(hThread : THandle);
      procedure DeregisterThread(hThread : THandle);
  End;

implementation

{ TSyncThread }

procedure TSyncThread.AddCalc(ACalc: String);
begin
  if Assigned(FCalculates) then
    FCalculates.Add(ACalc);
end;

constructor TSyncThread.Create;
begin
  FCalculates := TStringList.Create;
  FreeOnTerminate := False;
  FRegistredThreads := 0;

  inherited Create(False);
end;

procedure TSyncThread.DeregisterThread(hThread: THandle);
var
  I : integer;
begin
  for I := 0 to FRegistredThreads do
    if FThreadHandles[I] = hThread then
    begin
      FThreadHandles := 0;
      DEC(FRegistredThreads);
    end;
end;

procedure TSyncThread.Execute;
begin
  while not Terminated do
  begin
    WaitForMultipleObjects(FRegistredThreads,
                           @FThreadHandles,
                           True,
                           INFINITE);

    //Die Ergebnise entweder Zwischenspeichern oder nicht oder wie auch immer
    //kannst natürlich auch waitall auf false setzen und dann alles immer wieder in die zwischenablage und dort vlt per addobject und dann immer das dazugehörige memo al object anhängen oder so
    //an VCL per Synchronize Ergebnisse übertragen
  end;
end;

function TSyncThread.GetNextFree: Integer;
var
  I : integer;
begin
  for I := 0 to High(FThreadHandles) do
    if FThreadHandles[I] = 0 then
    begin
      Result := I;
      Exit;
    end;
end;

procedure TSyncThread.RegisterThread(hThread: THandle);
begin
  FThreadHandles[GetNextFree] := hThread;
  INC(FRegistredThreads);
end;

end.
Hab die Unit auch nochmal angehangen. Ist aber nicht getestet!
EDIT:
Also wie ich mir das gedacht habe: Wenn die einzelnen Threads fertig sind, melden sie ihr Ergebnis an AddCalc, dort kannst du dann String und Memo abspeichern und fertig.
Die Subthreads haben in ihren Konstruktoren die Registrierung und in ihren Destruktoren die Deregistrierung an dieser Klasse implementiert.
Die Syncthread-Klasse musst du selber freigeben, die Subthreads enden wenn gebraucht selbst. Wie du halt willst.

In welchen Abständen du nun alles abgleichst und dann an die VCL schickst, ist dir überlassen. Kannst ja alles mit der Zeit, mit der du wartest steuern ...

Obiger Beispielcode habe ich unter Zeitdruck gemacht, hab hier Urlaubsvorbereitungen. Also viel Spaß damit ich lese in ein paar Tagen die Ergebisse weiter
Angehängte Dateien
Dateityp: pas unit2_957.pas (1,7 KB, 1x aufgerufen)
Lars S.
Wer nicht mit der Zeit geht, geht mit der Zeit.
  Mit Zitat antworten Zitat