我创建了一个派生自TThread的类,因为我希望做一些异步的东西,但是为了避免创建另一个类,我在该线程类周围构建了整个东西。不确定这是不是很好的做法,如果我不能让它工作,那么我想我别无选择,只能重新编码......
问题:我在FormCreate上创建了Thread,分配了一些属性,并在FormDestroy上释放它。在Thread的构造函数中,我设置了FreeOnTerminate = False
。当我单击表单上的按钮时,我Start();
线程。好吧,所以它按预期运行,发生错误(预期!),它被传递给我的错误处理事件,似乎终止。然后我再次单击该按钮,我收到Cannot call Start on a running or suspended thread
错误。
如何在不释放线程的情况下完成线程,并让我再次启动它?
答案 0 :(得分:6)
完成/终止后,您无法重新启动线程。在这种情况下,如果线程再次像在FormCreate中那样创建一个新实例。
答案 1 :(得分:5)
捕获线程中的错误,在那里处理它然后让线程继续工作。例如,要处理错误,您可以简单地将方法排队到主线程以报告错误。我希望你不要让异常离开你的线程执行方法。
答案 2 :(得分:1)
这是我实现它的方式:
procedure TAPIRequest.DoRequest;
begin
FBusy := True;
Resume;
end;
procedure TAPIRequest.Execute;
begin
inherited;
while not Terminated do begin
HttpError := False;
try
Response := HTTP.Post(URL, Params);
ParseResponse;
except
HttpError := True;
end;
if Assigned(OnResponse) then
OnResponse();
FBusy := False;
Suspend;
end;
end;
答案 3 :(得分:0)
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
var
Form1: TForm1;
MyThread: TMyThread;
Event: TEvent;
procedure TForm1.FormCreate(Sender: TObject);
begin
Event := TEvent.Create(nil,true,false, '');
MyThread := TMyThread.Create(False);
end;
procedure TMyThread.Execute;
begin
while True do
begin
Event.WaitFor(Infinite);
// do something
Event.ResetEvent;
end;
end;
procedure RestartThread;
begin
Event.SetEvent;
// if you need check thread status, wait or run, use here
// if Event.WaitFor(0) = ...(wrTimeout, wrSignaled)
end;