[英]What's the correct way in Delphi to check if a non-Suspended created TThread with FreeOnTerminate = True is still executing?
所以我创建了一个 class: TWorkerThread = class(TThread)
。 在TWorkerThread
构造函数中,我设置FreeOnTerminate:= True
。
然后,我向我的TForm
添加了一个私有Worker
变量。 当我为Worker
实例化TWorkerThread
时,我总是使用CreateSuspended:= False
。
一旦启动,我需要与线程进行的唯一交互是取消进程( Terminate
)并检查进程是否结束(该检查是基于用户事件的)。
要检查线程是否仍处于活动状态,我会:
if (Self.Worker <> nil) and (not Self.Worker.Finished) then
//Still active
这似乎工作正常,但我担心有时TWorkerThread
将是<> nil
但仍然是.free
(记住TWorkerThread
都是FreeOnTerminate:= True
)。 当TWorkerThread
“自我毁灭”一旦终止时,它们是否总是变为nil
? 如果没有,我该如何处理(以避免访问冲突)?
另一件事,如果一个Worker
在它的表单销毁上是活跃的,我会这样做:
if (Self.Worker <> nil) and (not Self.Worker.Finished) then
begin
Self.Worker.Terminate;
//wait here for completion
end;
Terminate
后,如果我执行WaitFor
,我会遇到访问冲突(因为自毁)。 我应该在这里强制等待吗? 最好的方法是什么?
这是我在 Delphi 中第一次正确使用 TThread。 上面的代码是我为清楚起见所做的简化版本。
Delphi 中检查 FreeOnTerminate = True 的非暂停创建的 TThread 是否仍在执行的正确方法是什么?
空无一人。
一旦启动自毁线程,您就不再被允许从外部代码中触摸持有此类线程的引用,因为该引用随时可能变得陈旧。
在某些情况下(如果在您的自定义线程类中DoTerminate
中的逻辑处理OnTerminate
调用),您可以安全地从OnTerminate
事件处理程序访问线程引用。 但是,这不会帮助您解决问题,因为您不能等待自毁线程。 在 Windows 上,此类代码会导致可以捕获和处理的异常,但在其他平台上,它会导致未定义的行为和随机死锁。 但即使在 Windows 上编写这样的代码也是不可取的。
如果您需要检查线程的状态,取消它或等待它,您不能使用自毁线程。 时期。 (对于那些可能在 object 之前声明的人,是的,在某些情况下,其中一些事情是可能的,但它们通常会导致自己的脚受伤)。
您可以将以下工作流与TWorkerThread
一起使用,前提是您在线程构造函数FreeOnTerminate
保留为False
并构造未挂起的线程。 必须从主线程调用以下所有方法,以避免Worker
引用上的竞争条件。 在您的表单打开时拥有一个不执行任何操作的额外线程不会给您带来任何麻烦。
procedure TMyForm.StartWorker;
begin
FreeAndNil(Worker); // or if Assigned(Worker) then Exit;
Worker := TWorkerThread.Create;
end;
procedure TMyForm.CancelWorker;
begin
// this will initiate thread termination and waiting
FreeAndNil(Worker);
end;
procedure TMyForm.Destroy;
begin
// technically we could only use Free here,
// but since other code requires niling the reference this is more consistent
FreeAndNil(Worker);
inherited;
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.