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.