Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Frage zu Thread mit FreeOnTerminate (https://www.delphipraxis.net/207740-frage-zu-thread-mit-freeonterminate.html)

iphi 28. Apr 2021 08:17

Frage zu Thread mit FreeOnTerminate
 
Hallo,

ich habe ein Threadobjekt, das sofort nach Create losläuft, etwas macht und sich dann wegen FreeOnTerminate selbst auflöst, wenn es fertig ist.
Ich erzeuge mein Threadobjekt so:

Delphi-Quellcode:
MyThread:=TMyThread.Create;
Wie kann ich feststellen, ob das Threadobjekt noch lebt?

a)
Delphi-Quellcode:
if assigned(MyThread) then ...
Ich habe aber den Eindruck, dass MyThread nicht auf NIL gesetzt wird, wenn der Thread sich selbst auflöst.

b) Ich könnte im Thread eine Variable Running anlegen:
Delphi-Quellcode:
if MyThread.Running then ...
Nach meinem Verständnis gibt es aber nach Beendigung des Threads das Objekt MyThread nicht mehr im Speicher. => Zugriffsverletzung

Wie mache ichs richtig?

Der schöne Günther 28. Apr 2021 08:23

AW: Frage zu Thread mit FreeOnTerminate
 
Zitat:

Zitat von iphi (Beitrag 1488044)
Wie kann ich feststellen, ob das Threadobjekt noch lebt?

Das
Delphi-Quellcode:
FreeOnTerminate
eben nicht verwenden.

Zitat:

Zitat von iphi (Beitrag 1488044)
Ich habe aber den Eindruck, dass MyThread nicht auf NIL gesetzt wird, wenn der Thread sich selbst auflöst

Richtig. Der Thread kann selbst auch gar nicht wissen, welche Variablen auf ihn zeigen.

Du musst dich entscheiden - Entweder du machst FreeOnTerminate, das heißt es ist Fire&Forget: Du startest den Thread und danach fasst du ihn nie wieder an. Deshalb macht es auch keinen Sinn ihn dann überhaupt in einer Variable zu speichern.

Oder du nutzt eben kein FreeOnTerminate, musst nachschauen wann er zu Ende ist, und wenn du ihn nicht mehr brauchst, gibst du ihn frei (.Destroy()).

Gandalf2265 28. Apr 2021 08:28

AW: Frage zu Thread mit FreeOnTerminate
 
ungetestet, sollte aber glaube ich gehen:
  • Eine eigene Methode im Thread für OnTerminate bauen
  • darin dann mit Synchronize in die Thread erzeugende Unit einen Wert schreiben
Dann wäre der Wert als Signal da wenn der Thread beendet ist.

himitsu 28. Apr 2021 08:30

AW: Frage zu Thread mit FreeOnTerminate
 
von Außen kannst darfst du es garnicht feststellen, da die Variable per-se ungültig ist, weil der Thread schon weg sein könnte.
Also im Grunde darfst du den erstellten Thread garnicht erst in einer Variable speichern.
Das Selbe gilt auch für TThread.CreateAnonymus, welches ja auch FreeOnTerminate nutzt.

Dein Thread kann aber über eine "globale" Variable oder über ein Event nach außen durchgeben, dass er fertig ist.
Also du mußt das dann im Code rausgeben. (entweder im Destroy des Threads oder Try-Finally im Execute)

iphi 28. Apr 2021 08:33

AW: Frage zu Thread mit FreeOnTerminate
 
OnTerminate-Methode ist eine gute Idee!
Vielen Dank für die Aufklärung und Eure Hilfe!

Noch eine Verständnisfrage:

Macht FreeOnTerminate dann überhaupt irgendwann einen Sinn?
Wenn der Thread noch läuft, wenn das Hauptprogramm beendet wird, dann kommts zum Crash.
Wie fängt man sowas ab?

dummzeuch 28. Apr 2021 08:37

AW: Frage zu Thread mit FreeOnTerminate
 
Zitat:

Zitat von Gandalf2265 (Beitrag 1488047)
ungetestet, sollte aber glaube ich gehen:
  • Eine eigene Methode im Thread für OnTerminate bauen
  • darin dann mit Synchronize in die Thread erzeugende Unit einen Wert schreiben
Dann wäre der Wert als Signal da wenn der Thread beendet ist.

Synchronize ist nur notwendig, wenn in der Methode auf die VCL zugegriffen wird. Wenn man also nur z.B. eine Boolean-Variable setzen will (oder einen Pointer auf NIL), kann man sich Synchronize sparen.

himitsu 28. Apr 2021 09:08

AW: Frage zu Thread mit FreeOnTerminate
 
wenn du keine eigenes try-except im Execute hast, dann ist OnTerminatee auch die Stelle wo du self.FatalException oder war's .FatalError (kannst das einfach nach "Exception casten" )prüfen solltest.

Die VCL zeigt ja Exceptions an, aber TThread macht das nicht von sich aus.
Der fängt es nur ab, da wenn eine Exception bis zum Windows durchrauscht der ganze Prozess beendet wird.

shebang 29. Apr 2021 13:25

AW: Frage zu Thread mit FreeOnTerminate
 
Zitat:

Zitat von iphi (Beitrag 1488049)
Wenn der Thread noch läuft, wenn das Hauptprogramm beendet wird, dann kommts zum Crash.
Wie fängt man sowas ab?

Du kannst im Thread an entsprechender Stelle prüfen, ob dein Hauptprogramm gerade beendet wird und darauf reagieren. Im Hauptprogramm müstest du dann allerdings warten, bis alle Threads beendet sind.

TigerLilly 29. Apr 2021 13:53

AW: Frage zu Thread mit FreeOnTerminate
 
Zitat:

Zitat von shebang (Beitrag 1488173)
Im Hauptprogramm müstest du dann allerdings warten, bis alle Threads beendet sind.

Das ist allerdings nicht so einfach.

himitsu 29. Apr 2021 13:58

AW: Frage zu Thread mit FreeOnTerminate
 
Zitat:

Zitat von TigerLilly (Beitrag 1488177)
Das ist allerdings nicht so einfach.

Jo, "FreeOnTerminate", also kann/darf man nicht von außen prüfen.
Da kann man nur in einer "globalen" Variable/Liste seine aktiven Threads "zählen" und dann warten, bis der Zähler/Liste 0 ist (was vom Thread aus gesetzt wird, wenn er sich beendet).

Die RTL führt am Ende zwar ein Halt aus, was den ganzen Prozess beendet, also auch Threads "abschießt" (damit Windows eben nicht wartet, bis alle Threads beendet sind, inkl. dem Hauptthread),
aber wenn bis dahin beim Beenden die Threads z.B. auf die RTL/VCL zugreifen, aber die Finalization der Units bereits durch sind, auch der Speichermanager (FastMM) sich beendet hat, dann kann es natürlich knallen, drum sollte man oftmals eben auf seine Threads warten, bevor das Beenden des Programms weiterläuft.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:48 Uhr.
Seite 1 von 2  1 2      

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