Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Wo wird Thread freigegeben? (https://www.delphipraxis.net/130339-wo-wird-thread-freigegeben.html)

TheMiller 6. Mär 2009 17:40


Wo wird Thread freigegeben?
 
Hallo.

Habe einen Thread, der nach Abschluss eine Methode der VCL aufruft. Habe also den Thread so konfiguriert:

Delphi-Quellcode:
  UpdateSucher:=TSeekUpdate.Create(True);
  UpdateSucher.OnTerminate:=AfterSeekUpdates;
  UpdateSucher.FreeOnTerminate:=False;
  UpdateSucher.Resume;
Wenn ich nun innerhalb der AfterSeekUpdates-Methode den Thread mit UpdateSucher.Free freigeben will, hängt das gesamte Programm unwiderruflich. Rufe ich UpdateSucher.free woanders auf, dann ist alles wunderbar. Nun meine Frage: Wo soll ich den Thread freigeben? Sofort funktioniert nicht, da ich auf Daten des Threads noch zugreifen muss - deswegen auch AfterSeekUpdates!

Danke

Apollonius 6. Mär 2009 17:45

Re: Wo wird Thread freigegeben?
 
TThread.Free ruft WaitFor auf, sodass es einen Deadlock gibt. Setze doch einfach FreeOnTerminate auf True, dann gibt sich der Thread nach dem OnTerminate selbst frei.

quendolineDD 6. Mär 2009 17:45

Re: Wo wird Thread freigegeben?
 
Einfach im Quelltext, wo du auch den Thread erstellst
Delphi-Quellcode:
  if Assigned(UpdateSucher) then
  begin
    FLogThread.Terminate;
    FLogThread.WaitFor;
    FreeAndNil(UpdateSucher);
  end;
Dann wird mit Terminate deine onTerminate-Methode aufgerufen und wenn er fertig terminiert ist, kannst du ihn beenden.

TheMiller 6. Mär 2009 19:34

Re: Wo wird Thread freigegeben?
 
Hm. ich weis nicht, ob ich das so richtig verstanden habe. Ich lasse den Thread ja extra nicht selbst zerstören, da ich noch auf Daten aus dem Thread zugreifen möchte. Und wenn ich den vorher geposteten Quelltext gleich nach dem erstellen aufrufe, dann wird er doch beendet, bevor er überhaupt fertig ist... also so:

Delphi-Quellcode:
  UpdateSucher:=TSeekUpdate.Create(True);
  UpdateSucher.OnTerminate:=AfterSeekUpdates;
  UpdateSucher.FreeOnTerminate:=False;
  UpdateSucher.Resume;

  if Assigned(UpdateSucher) then
  begin
    FLogThread.Terminate;
    FLogThread.WaitFor;
    FreeAndNil(UpdateSucher);
  end;
Das ist so bestimmt nicht richtig, oder?

thkerkmann 6. Mär 2009 19:39

Re: Wo wird Thread freigegeben?
 
Hi,

die "OnTerminate" Prozedur wird in jedem Fall vor dem Freigeben des Threads aufgerufen.
Erst danach wird der Thread sich selbst freigeben. Solltest Du also nur in dieser Methode auf die Daten des Thread zugreifen wollen, ist das vollkommen in Ordnung.

Gruss

TheMiller 6. Mär 2009 19:48

Re: Wo wird Thread freigegeben?
 
Ich weis nicht, ob wir aneinander vorbeireden...

wenn ich den Thread erstelle und SOFORT folgenden Code direkt unter das Erstellen schreibe, dann wird der Thread doch garnicht bis zum Schluss ausgeführt. Die Daten hole ich mir aus dem OnTerminate-Ereignis. Ich meine diesen Code

Delphi-Quellcode:
if Assigned(UpdateSucher) then
  begin
    FLogThread.Terminate;
    FLogThread.WaitFor;
    FreeAndNil(UpdateSucher);
  end;
Oder kann ich das Erstellen und Terminieren untereinanderschreiben, ohne dass der Ablauf der Threads terminiert wird?

mirage228 6. Mär 2009 19:52

Re: Wo wird Thread freigegeben?
 
Zitat:

Zitat von DJ-SPM
Sofort funktioniert nicht, da ich auf Daten des Threads noch zugreifen muss - deswegen auch AfterSeekUpdates!

Also ich sehe da kein Problem mit FreeOnTerminate := True. Du solltest im OnTerminate noch auf die Daten zugreifen können, der Thread wird anschließend freigegeben. Im OnTerminate kannst Du natürlich Diene Variable "UpdateSucher" auf nil setzen, falls Du die öfter verwenden willst...

TheMiller 6. Mär 2009 19:55

Re: Wo wird Thread freigegeben?
 
Hm.. :gruebel:

da hast du auch wieder Recht. Das habe ich einfach übersehen bzw nicht bedacht. Ich werde das so mal machen. Wenn's nicht klappt, dann werden wir uns hier bestimmt nochmal lesen - aber wieso sollte das nicht funktionieren.

Danke

quendolineDD 6. Mär 2009 19:56

Re: Wo wird Thread freigegeben?
 
Also:
Du erstellst den Thread, er geht über in die Execute Methode.
Gleich danach terminierst du diesen, daher wartet der Thread bis er die Execute-Methode verlassen hat und geht über in die von dir festgelegte onTemrinate-Methode. In dieser greifst du die Werte von bestimmten Eigenschaften ab und abschließend geht der Thread auch aus dieser Methode weiter.
MIt WaitFor wird gewartet, bis der Thread sich selber beendet hat, ehe mit FreeAndNil die Instanz aus dem Speicher gelöscht wird.

Es wäre wohl trotzdem besser, du stellt FreeonTerminate auf True und greifst wie zuvor in deiner onTerminate-Methode auf die Eigenschaften zu. Dann kannst du gewiss sein, das dein Thread fertig geworden ist. Setzt du noch einen Rückgabewert für das Beenden und wartest im Quellcode mit WaitForSingleObject(UpdateSucher.Handle, INFINITE) = <RückgabeWert>; bist du ebenfalls auf der sicheren Seite ...
Aber sowas schlug ja Apollonius in #2 schon vor.

TheMiller 6. Mär 2009 19:59

Re: Wo wird Thread freigegeben?
 
Vielen Dank für die Erklärung. Wusste nicht, dass der Thread die Execute-Methode trotzdem bis zum Schluss ausführt! Danke


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:44 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz