Einzelnen Beitrag anzeigen

HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
961 Beiträge
 
Delphi 6 Professional
 
#10

AW: TThread gibt beim Beenden Speicherleck

  Alt 2. Mär 2019, 16:57
Hmm..


.Terminate() solltest du grundlegend immer vermeiden. Das erzeugt nämlich seinerseits Memory Leaks, wenn der Thread noch Speicher reserviert hat, den er nicht mehr freigeben kann. Ist beim Programmende allerdings im Grunde so oder so egal. Deine Bedingung trifft nicht zu, da .FreeOnTerminate := true zwar den Thread freigibt, nicht aber die Referenz (deine Variable) auf nil setzt.

Ich persönlich würde auf .FreeOnTerminate := true verzichten und beim Programmende (z.B im OnClose des MainForms) die .WaitFor() Methode nutzen und danach den Thread selbstständig mit .Free() freigeben. Du kannst zusätzlich auch noch Thread.Terminated() überschreiben und dort eine private Statusvariable setzen. Für den Fall, dass der Thread Aufgaben in einer Schleife bearbeitet, kannst du dann dieses interne Feld als zusätzliche Schleifenbedingung nutzen.

Aus meiner Sicht ist das Blödsinn!!!

Zitat aus der Delphi Hilfe (hier D6):

Zitat:
TThread.Terminate

Die Methode Terminate signalisiert die Beendigung eines Threads. Dazu wird die Eigenschaft Terminated auf True gesetzt.

procedure Terminate;

Beschreibung

Terminate setzt die Eigenschaft Terminated des Thread auf True und signalisiert, daß der Thread so bald wie möglich beendet werden sollte. Im Gegensatz zu der Windows-API-Methode TerminateThread, die den Thread sofort beendet, fordert die Methode Terminate den Abbruch des Thread nur an. Dadurch kann der Thread vor seiner Beendigung noch erforderliche Aufräumarbeiten durchführen.

Die Methode Execute eines Threads sowie alle von Execute aufgerufenen Methoden sollten die Eigenschaft Terminated regelmäßig abfragen und die Ausführung gegebenenfalls beenden.



TThread.Terminated

Die Eigenschaft Terminated zeigt an, ob der Thread eine Aufforderung zum Beenden erhalten hat.

property Terminated: Boolean;

Beschreibung

Die Methode Execute des Threads sollte ebenso wie alle Methoden, die von Execute aufgerufen werden, die Eigenschaft Terminated abfragen und gegebenenfalls die Ausführung beenden. Die Methode Terminate setzt die Eigenschaft Terminated auf True.

Die Methode Terminate bietet ein Verfahren, einen Thread kontrolliert abzubrechen, wobei allerdings die Kooperation des Execute-Codes Voraussetzung ist.

Somit braucht hier nichts 'Überschrieben' werden, weil TThread.Terminate mit der Abfrage nach 'Terminated' in der Execute Methode genau das macht was notwendig ist!

Somit statt 'FreeOnTerminate := True;' einzubauen, einfach das 'Terminated' abfragen...

Zum Beenden eines Threads im Destroy (ohne FreeOnTerminate := True) somit das

Delphi-Quellcode:
Thread.Terminate; // Dem Thread 'signalisieren' dass er sich beenden soll (Sprich alles in Execute beenden und raus)
Thread.WaitFor; // Warten, bis Execute abgeschlossen
Thread.Free; // Thread freigeben..
  Mit Zitat antworten Zitat