Einzelnen Beitrag anzeigen

Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 

Re: Probleme beim Warten auf 2 Threads

  Alt 26. Nov 2006, 16:52
Hallo Rolf.

Ich beschreibe dir hier das Konzept noch einmal etwas genauer. Im Anhang habe ich das Konzept in einem Beispielprojekt gezeigt.

Das Konzept für 2 Threads

Du willst auf die Beendigung zweier Threads warten. Dafür bietet sich das OnTerminate-Ereignis der Klasse TThread an. Die Ereignisbehandlungsroutine braucht die Informationen über
  • den Thread, der abgeschlossen ist
  • den anderen Thread, ob er noch läuft oder nicht.
Nun ist die Sache einfach. Aus der ersten Information kann geschlussfolgert werden, welcher Thread als beendet markiert werden kann. Das kann nicht mithilfe des Threads selbst passieren, da sich dieser nach Beendigung selbst freigibt (FreeOnTerminate = True). Aus der zweiten Information kann geschlussfolgert werden, ob beide Threads damit beendet sind.

Ein Beispiel

Im Beispiel habe ich die Klasse TSleepThread von TThread abgeleitet. Die Aufgabe ist eine bestimmte Zeit zu schlafen. Anschließend ist der Thread beendet. Wie lange geschlafen werden soll wird im Kontruktor angegeben. Ther Parameter CreateSuspended wird an den Kontruktor von TThread weitergereicht. Kurzfassung:
Delphi-Quellcode:
type
  TSleepThread = class(TThread)
  ...

constructor TSleepThread.Create(const Milliseconds: Cardinal; const CreateSuspended: Boolean);
Zum Formular habe ich 2 Variablen (Eigenschaften) hinzugefügt: FThread1 (Thread1) und FThread2 (Thread2). Beide sind von der Klasse TSleepThread. Diese Felder dienen nur zum Merken, ob ein Thread beendet ist (= nil) oder nicht (<> nil). Kurzfassung:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    private
    FThread1, FThread2: TSleepThread;

    published
    property Thread1: TSleepThread read FSleepThread1 write FSleepThread1;
    property Thread2: TSleepThread read FSleepThread2 write FSleepThread2;
  end;
Die Methode RunThreads initialisiert und startet die Threads. Kurfassung:procedure RunThreads; Der Kern liegt in der Methode DoTerminate. Diese wurde den erzeugten Threads dem Ereignis OnTerminate zugewiesen. Neben einer Ausgaberückmeldung setzt diese Methode die Merker Thread1 bzw. Thread2 auf Nil, wenn der zugehörige Thread beendet wurde. Wurden beide abgearbeitet, sind folglich beide Nil. Das ist also der Zustand, nach dem du gesucht hast. Kurzfassung:
Delphi-Quellcode:
procedure TForm1.DoTerminate(Sender: TObject);
begin
  { Merker setzten, dass ein Thread beendet wurde. }
  if Sender = Thread1 then Thread1:=nil else
  if Sender = Thread2 then Thread2:=nil;
  { Fall, dass beide Threads beendet wurden. }
  if not Assigned(Thread1) and not Assigned(Thread2) then...;
end;
Damit ergibt sich also nicht mehr das Problem, dass das Programm "hängt".

Viel Spaß beim ausprobieren mit dem Beispiel. Ich habe es so gestaltet, dass man die "Laufzeit" der Threads einfach in der Oberfläche einstellen kann.

Beispiel erstellt und getestet mit Delphi 7 Enterprise.

Gruß,
Panthrax.

[edit=Panthrax]Glatt den Anhang vergessen... Jetzt ist er dabei.[/edit]
Angehängte Dateien
Dateityp: rar auf_2_threads_warten_208.rar (1,7 KB, 21x aufgerufen)
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat