![]() |
AThread.WaitFor gibt Fehler "Das Thread Handle ist ungü
Hallo,
ich habe einge eigene Thread-Klasse erstellt. Threads dieser Klasse sollen, wenn sie mit der Execute-Methode fertig sind, automatisch freigegeben werden. Deshalb ist AThread.FreeOnTerminate := True; gesetzt. Jedoch soll es auch die Möglochkeit geben, den Thread per Button-Click vor Ende der Execute-MEthode abzubrechen. Im Beispiel unten passiert das mit Button2Click. Dort tritt auch der Fehler auf: Wird Button2Click ausgelößt, wenn der Thread noch läuft ist alles ok. Wenn der Thread jedoch schon beendet ist, gibt es den Fehler "Das Thread Handle ist ungültig". Unz war bei AThread.WaitFor; An dieser STelle muss jedoch gewartet werden, weil danach noch Code folgt, der erst ausgeführt werden darf, wenn der Thread nicht mehr läuft. Wie bekomme ich also beides (Beenden per Klick und automatisch freigeben) unter einem Hut?
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TMyThread = class(TThread) public procedure Execute; override; end; TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private AThread: TMyThread; procedure MyThreadTerminate(Sender: TObject); public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} //Erzeugt den Thread procedure TForm1.Button1Click(Sender: TObject); begin AThread := TMyThread.Create(True); AThread.Priority := tpNormal; AThread.FreeOnTerminate := True; AThread.OnTerminate := MyThreadTerminate; AThread.Resume; end; //Gibt dem Benutzer die Möglichkeit, den Thread zu Beenden procedure TForm1.Button2Click(Sender: TObject); begin if Assigned(AThread) then begin AThread.Terminate; AThread.WaitFor; //Hier fehler! end; //Hier steht noch Code, der erst ausgeführt werden darf, wenn AThread beendet ist. end; procedure TForm1.MyThreadTerminate(Sender: TObject); begin AThread := nil; end; { TMyThread } procedure TMyThread.Execute; var i: Integer; begin i := 0; while not Terminated do begin sleep(100); inc(i); if i = 100 then //Beendet den Thread nach 10 Sekunden. Nur zum Testen. break; end; end; end. |
Re: AThread.WaitFor gibt Fehler "Das Thread Handle ist
Hallo,
Delphi-Quellcode:
Noch eine Anmerkung, Du bekommst nicht mit wenn Dein Thread "normal" terminiert.
//Gibt dem Benutzer die Möglichkeit, den Thread zu Beenden
procedure TForm1.Button2Click(Sender: TObject); begin if Assigned(AThread) then begin AThread.Terminate; // hier wird der Thread auf nil gesetzt, siehe Deine OnTerminate Routine AThread.WaitFor; //Hier fehler! end; //Hier steht noch Code, der erst ausgeführt werden darf, wenn AThread beendet ist. end; Grüße Klaus Grüße Klaus |
Re: AThread.WaitFor gibt Fehler "Das Thread Handle ist
Wenn FreeOnTerminate gesetzt ist, geht WaitFor schlicht nicht.
Folgendes Szenario:
Delphi-Quellcode:
Also: Wenn du unbedingt auf den Thread warten musst, dann geht das nur wenn du ihn hinterher selbst freigibst.
// Im MainThread:
ThreadInstance.Terminate; // -> Threadwechsel // ThreadInstance terminiert und verschwindet aus dem Speicher // -> Threadwechsel zum MainThread ThreadInstance.WaitFor; // ThreadInstance hat noch einen Wert, ist aber ungültig -> Exception |
Re: AThread.WaitFor gibt Fehler "Das Thread Handle ist
Zitat:
Eine Möglichkeit ist, beim Button-Click ein Flag zu setzen und den Code, der nach Beenden des Threads ausgeführt werden soll, im MyThreadTerminate aufzurufen.
Delphi-Quellcode:
procedure TForm1.MyThreadTerminate(Sender: TObject);
begin AThread := nil; if FlagDoSomeCode then begin FlagDoSomeCode := false; DoSomeCode; end; end; procedure TForm1.Button2Click(Sender: TObject); begin if Assigned(AThread) then begin FlagDoSomeCode := true; AThread.Terminate; end else begin DoSomeCode; end; end; |
Re: AThread.WaitFor gibt Fehler "Das Thread Handle ist
So müsste es funktionieren:
Delphi-Quellcode:
//Erzeugt den Thread
procedure TForm1.Button1Click(Sender: TObject); begin AThread := TMyThread.Create(True); AThread.Priority := tpNormal; //AThread.FreeOnTerminate := True; //Nicht automatisch freigeben //AThread.OnTerminate := MyThreadTerminate; //Braucht man nicht außer du willst noch was anderes darin machen AThread.Resume; end; //Gibt dem Benutzer die Möglichkeit, den Thread zu Beenden procedure TForm1.Button2Click(Sender: TObject); begin if Assigned(AThread) then begin AThread.Terminate; AThread.WaitFor; FreeAndNil(AThread); end; //Hier steht noch Code, der erst ausgeführt werden darf, wenn AThread beendet ist. end; |
Re: AThread.WaitFor gibt Fehler "Das Thread Handle ist
Zitat:
|
Re: AThread.WaitFor gibt Fehler "Das Thread Handle ist
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:14 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 by Thomas Breitkreuz