您的线程Execute
方法必须定期检查线程Terminated
属性的状态。如果是True
,则线程Execute
方法必须退出。
因此,典型的Execute
方法可能如下所示:
procedure TMyThread.Execute;
begin
while not Terminated do
DoNextPieceOfWork
end;
看起来您的线程有自己的FActive
标志,正在执行相同的任务。问题在于TThread
它不知道。因此,您应该摆脱FActive
并使用内置机制。
当您调用Free
线程时,它将调用Terminate
. 那将Terminated
是True
。然后它等待线程方法退出。这会发生,因为您的线程注意到它Terminated
并True
退出。然后线程的析构函数可以继续并完成整理线程的工作。
查看答案中的代码,最好使用现有Terminate
机制编写。
type
TMyThread = class(TThread)
private
FTerminateEvent: TEvent;
protected
procedure Execute; override;
procedure TerminatedSet; override;
public
constructor Create(ACreateSuspended: Boolean);
destructor Destroy; override;
end;
constructor TMyThread.Create(ACreateSuspended: Boolean);
begin
inherited Create(ACreateSuspended);
FTerminateEvent := TEvent.Create(nil, True, False, '');
end;
destructor TMyThread.Destroy;
begin
inherited;
FTerminateEvent.Free;
end;
procedure TMyThread.TerminatedSet;
begin
FTerminateEvent.SetEvent;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
// do somthing interesting!
FTerminateEvent.WaitFor(5000);
end;
end;
现在不需要单独的Stop
方法。你可以Free
在线程上调用。然后Terminate
被调用。然后TerminatedSet
被调用。然后发出事件信号。然后Execute
终止。然后线程可以消失。
话虽如此,我正在努力想一个 5000 毫秒超时将是最佳方法的场景。我不知道您为什么要这样做,但我猜您正在尝试限制线程以使其不会运行hot。你想避免一个繁忙的循环。这是令人钦佩的,但使用固定超时不是这样做的方法。这样做的方法是等待一个同步事件,通常是一个事件。然后当有更多工作要做时,事件会发出信号并且您的线程会唤醒。