![]() |
Freigeben eines suspended Threads
Hab da mal eine Frage zu folgendem minimalen Programmcode mit einem Thread.
Hauptprogramm:
Delphi-Quellcode:
Thread:
type
TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } myThread: TmyThread; end; var MainForm: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin myThread := TmyThread.Create(true); myThread.FreeOnTerminate := true; // myThread.Start; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if (myThread <> nil) then begin if not myThread.Suspended then //Thread ist gestartet begin myThread.Terminate; while not myThread.Finished do sleep(10); end else //Thread wurde nicht gestartet myThread.Free; end; end;
Delphi-Quellcode:
Es geht dabei um die Frage was korrekterweise im FormClose stehen müsste. Wenn der Thread gestartet ist, alles ok. Wenn aber nicht, dann befindet sich der Thread bei Close im suspended-Zustand. myThread.Free bring eine Exception 'Thread Error: Das Handle ist ungültig'. Ohne myThread.Free gibt es ein Memory Leakage.
type
TmyThread = class(TThread) protected procedure Execute; override; end; implementation procedure TmyThread.Execute; begin while not Terminated do begin Sleep(50); end; end; Wie kann man das Leakage vermeiden, also das Objekt korrekt freigeben? |
AW: Freigeben eines suspended Threads
Delphi-Quellcode:
myThread.Terminate;
if myThread.Suspended then myThread.Start; //falls Free nicht wartet (bin mir grade nicht sicher), dann hier warten bis Thread sich beendet hat myThread.Free; |
AW: Freigeben eines suspended Threads
Mmhh, die Lösung, den Thread zwangsweise im FormClose zu starten, finde ich irgendwie befremdlich. Wieso wird das Objekt mit Free nicht freigegeben wie jedes andere auch?
|
AW: Freigeben eines suspended Threads
Wundert mich ehrlich gesagt auch, dass das Handle angeblich invalid sein soll. Die Klasse erstellt ja den Thread ganz normal per CreateThread() / BeginThread(). Auch wenn er anfangs suspended ist, darf das Handle nicht invalid sein, sonst könnte man den Thread ja überhaupt nicht mehr resumen.
Ah, lass mal das FreeOnTerminate auf false. Ich vermute hier wird irgendwie 2x versucht den Thread zu terminieren und beim 2. Versuch ist dann das Handle ungültig. |
AW: Freigeben eines suspended Threads
Yep, bin da auch eben dahintergekommen. Also es klappt sauber mit
Delphi-Quellcode:
Danke.
if (myThread <> nil) then
begin if not myThread.Suspended then begin myThread.Terminate; while not myThread.Finished do sleep(10); end else begin myThread.FreeOnTerminate := false; // <-------- hinzugefügt myThread.Free; end; end; |
AW: Freigeben eines suspended Threads
Du solltest dich entscheiden, wer hier die Kontrolle hat.
- entweder du, dann FreeOnTerminate immer auf false und manuelles Free - oder der Thread, dann FreeOnTerminate true und niemals Free |
AW: Freigeben eines suspended Threads
Zitat:
einfach danke. Mir fällt es wie Schuppen von den Haaren ... Die meisten Beuspiele sind immer mit FreeOnTerminate := true; und so bin ich da ebenfalls reingestolpert. Aber die DH sagt auch Zitat:
Delphi-Quellcode:
Das klappt egal ob der Thread gestartet ist oder nicht.
procedure TForm1.FormCreate(Sender: TObject);
begin myThread := TmyThread.Create(true); //... evtl. weitere Initialisierung, daher createsuspended myThread.Start; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin myThread.Free; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:19 Uhr. |
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