Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TThread: Wie frei geben? Bekomme beim Beenden Memory Leak (https://www.delphipraxis.net/204181-tthread-wie-frei-geben-bekomme-beim-beenden-memory-leak.html)

juergen 3. Mai 2020 16:28

TThread: Wie frei geben? Bekomme beim Beenden Memory Leak
 
Hallo zusammen,

beim starten meines Programms auf einem Client prüfe ich ob die lokale Hilfedatei
a) vorhanden ist
b) die aktuelle Version hat (auf einem Server liegt die aktuelle Hilfedatei)

Da das im Hintergrund laufen soll, habe ich gedacht das in einen eigenen Thread auszuführen, einmalig beim Start.
Funktioniert auch, außer dass nun beim Beenden des Programms ein Memory Leak auftaucht:
Zitat:

---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:

53 - 60 bytes: my_HelpFileThread x 1

---------------------------
OK
---------------------------
Der Thread ist eigentlich super einfach:
Delphi-Quellcode:
UNIT u_HelpFileThread;

INTERFACE

USES
  System.Classes, System.IOUtils, System.SysUtils, WinApi.Windows;

TYPE
  my_HelpFileThread = CLASS( TThread )
  PRIVATE
    { Private-Deklarationen }
  VAR
  ls_FileNameAndPath_local, ls_FileNameAndPath_Server: PWideChar;
  PROTECTED
    PROCEDURE Execute; OVERRIDE;

  END;

IMPLEMENTATION


PROCEDURE my_HelpFileThread.Execute;
BEGIN
  TRY
  // hier meine Abarbeitung der Aufgabe
  FINALLY
    Terminate;
  END;
END;
In der Hauptform im OnShow() habe ich folgendes stehen:
Delphi-Quellcode:
...
  u_HelpFileThread.my_HelpFileThread.Create;
...
Ich finde nun keine Möglichkeit meine Thread Klasse freizugeben mit Free oder ähnlichem.

Wie muss man das machen?

Vielen Dank vorab!

jaenicke 3. Mai 2020 16:34

AW: TThread: Wie frei geben? Bekomme beim Beenden Memory Leak
 
FreeOnTerminate auf True setzen im Konstruktor des Threads genügt schon.

Das darf man aber nur machen, wenn man den erzeugten Thread nur einfach laufen lässt und nicht in einer Variablen hält und darauf zugreift. (Klar, der Thread könnte ja schon freigegeben sein beim Zugriff.)

juergen 3. Mai 2020 16:47

AW: TThread: Wie frei geben? Bekomme beim Beenden Memory Leak
 
Vielen Dank, für meinen Fall passt das! :thumb:

Allen noch einen schönen Sonntag!

himitsu 4. Mai 2020 00:02

AW: TThread: Wie frei geben? Bekomme beim Beenden Memory Leak
 
Wenn sich dein Programm beendet, dann mußt du auch den Thread beenden,
oder es muß sicherestellt sein, dass er nur kurz läuft und schon vor dem Programmende sich beendet und freigegeben hat.


Man könnte z.B. im Thread aus Application.Terminated prüfen, bzw. dem Thread von außen ein Signal (Thread.Terminate oder ein Event oder eine Variable) schicken
und dann ein bissl warten, bis der Thread aus ist, denn wenn der Thread noch läuft, während der Hauptthread anfängt den Speichermanager aufzuräumen/beenden, dann hast immernoch ein Speicherleck.


Zitat:

Delphi-Quellcode:
PROCEDURE my_HelpFileThread.Execute;
BEGIN
  TRY
  // hier meine Abarbeitung der Aufgabe
  FINALLY
    Terminate;
  END;
END;

Wenn das Execute verlassen wird, ist das automatisch ein Terminate.

Außerdem ist es sinnlos Terminate zu setzen, wenn DU im Execute nie auf Terminated prüfst, denn Terminate macht nichts anderes, als diese Variable zu setzen.

Delphi hat auch beteits ein try-except um das Terminate drumrum aufgebaut, (genauso wie in der VCL um praktisch alle Methoden drumrum)
denn wenn im Windows eine Exception bis zum System durchrauscht, dann wird der komplette Prozess beendet. (du kennst bestimmt auch keinen Entwickler, der niemals eine Exception erzeugt, da wäre das echt blöd)


Einziger Nachteil, dass man nur über OnTerminate oder DoTerminate an diese Exception ran kommt (Property FatalException ist nur dort gesetzt, wenn Execute mit einer Exception abrauchte) und dass Delphi dort den Fehler nicht ausgibt (so wie in der VCL dann der Fehlerdialog kommt) ... sowas müsste man im OnTerminate selbst machen, weil Delphi das leider nicht standardmäßig macht.

juergen 4. Mai 2020 00:31

AW: TThread: Wie frei geben? Bekomme beim Beenden Memory Leak
 
@himitsu,

danke für die Hinweise!
Zitat:

Wenn das Execute verlassen wird, ist das automatisch ein Terminate.
Das hatte ich ich auch in der Hilfe gelesen, war dann aber noch ein Überbleibsel aus einigen Versuchen von mir.

Zitat:

Außerdem ist es sinnlos Terminate zu setzen, wenn DU im Execute nie auf Terminated prüfst, denn Terminate macht nichts anderes, als diese Variable zu setzen.
Gut zu wissen!


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:19 Uhr.

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