Die Spiecherlecks werdn doch deshalb angezeigt, weil die Threads beim Beenden des Prozesses einfach abgeschossen werden und die von jedem Thread belegten Ressourcen nicht freigeben wurden.
Wenn man das nicht haben möchte, dann muss man sich eben selber um die Freigabe der Threads kümmern und nicht
TThread.FreeOnTerminate := True;
wegdelegieren.
BTW: Das hier ist grober Unfug:
Delphi-Quellcode:
Constructor TCalcThread.Create(Codec: TCodecType; Bitmap: TBitmap;
OnCalcDone: TOnCalcDone);
Begin
fSize:= -1;
// ungültigen Wert vorgeben
fCodec:= Codec;
// Codec merken
fOnCalcDone:=OnCalcDone;
// Zeiger auf Ereignis merken
fBitmap:=TBitmap.Create;
// TBitmap anlegen
fBitmap.Assign(Bitmap);
// Bild kopieren
FreeOnTerminate:=True;
// Speicher selbst freigeben
Inherited Create(True);
// Thread erstellen
Priority:= tpIdle;
// geringe Priorität
// Resume; // "Start" löst Exception aus!
Start;
// "Resume" ist veraltet
End;
Während der
Constructor
abgearbeitet wird wird der Thread
nicht loslaufen! Mit der Erkenntnis kann der Code wie folgt geschreiben werden:
Delphi-Quellcode:
Constructor TCalcThread.Create(Codec: TCodecType; Bitmap: TBitmap;
OnCalcDone: TOnCalcDone);
Begin
fSize := -1; // ungültigen Wert vorgeben
fCodec := Codec; // Codec merken
fOnCalcDone := OnCalcDone; // Zeiger auf Ereignis merken
fBitmap := TBitmap.Create; // TBitmap anlegen
fBitmap.Assign( Bitmap ); // Bild kopieren
Inherited Create( False ); // Thread erstellen
Priority := tpIdle; // geringe Priorität
FreeOnTerminate := True; // Instanz selbst freigeben <- hmmm, nicht geschickt
End;
Der
Destructor
sollte allerdings wie folgt aufgebaut werden:
Delphi-Quellcode:
Destructor TCalcThread.Destroy;
Begin
fOnCalcDone:=nil; // Zeiger löschen
Inherited; // den Rest ausführen
fBitmap.Free; // TBitmap selbst freigeben
End;
In
TThread.Destroy
wird unter anderem
TThread.Terminate
aufgerufen, weil der Thread ja noch aktiv sein kann. Wenn man dem Thread
während der Abarbeitung die Ressource
fBitmap unter dem A.... wegzieht, was kann dann passieren? Genau, es knallt. Also erst
inherited
, danach ist der Thread
gesichert beendet und dann können alle Ressourcen ohne Reue freigeben werden!