Delphi 为什么可以';我不能在外部创建的线程上调用CheckTerminated吗?

Delphi 为什么可以';我不能在外部创建的线程上调用CheckTerminated吗?,delphi,delphi-xe2,Delphi,Delphi Xe2,当我运行此代码时: FMyThread := TThread.createAnonymousThread( procedure begin while not FMyThread.CheckTerminated do begin sleep(750); TThread.synchronize(nil, procedure begin if FMyThread.CheckTerminat

当我运行此代码时:

  FMyThread := TThread.createAnonymousThread(
   procedure
   begin
     while not FMyThread.CheckTerminated do begin
       sleep(750);
       TThread.synchronize(nil,
         procedure
         begin
           if FMyThread.CheckTerminated then exit;
           ....
         end);
     end;
   end);
   FMyThread.start;
我有个例外

无法在外部创建的线程上调用CheckTerminated


为什么?

如果您查看CheckTerminated的实现,您会注意到它不是一个方法,而是一个静态类方法

CheckTerminated
指示当前执行的线程是否将其
终止
标志设置为
TRUE
。在TThread.synchronize内调用FMyThread.CheckTerminated时,它不会检查FMyThread.Terminated,而是尝试检查“GetCurrentThreadId”的状态,在本例中,它是进程的主线程

由于主线程不是由TThread创建的,因此RTL会创建一个
TExternalThread
(请参见
类函数TThread.GetCurrentThread:TThread

换句话说,如果您有一个TThread对象,并且想要检查它是否被终止,那么应该调用
terminated
,而不是
CheckTerminated


由于默认情况下,匿名线程在终止时被释放,因此需要确保清除
OnTerminate
处理程序中对线程的任何引用。

如果查看CheckTerminated的实现,您会注意到它不是一个方法,而是一个静态类方法

CheckTerminated
指示当前执行的线程是否将其
终止
标志设置为
TRUE
。在TThread.synchronize内调用FMyThread.CheckTerminated时,它不会检查FMyThread.Terminated,而是尝试检查“GetCurrentThreadId”的状态,在本例中,它是进程的主线程

由于主线程不是由TThread创建的,因此RTL会创建一个
TExternalThread
(请参见
类函数TThread.GetCurrentThread:TThread

换句话说,如果您有一个TThread对象,并且想要检查它是否被终止,那么应该调用
terminated
,而不是
CheckTerminated


由于AnonymousThread默认情况下在terminate时被释放,因此您需要确保在
ontterminate
处理程序中清除对线程的任何引用。

检查页面,我认为它可以帮助您注意一点,保留对匿名线程的引用并期望使用它是非常危险的。一旦启动它,它就没有意义了,因为线程可能会在您想要使用它的时候终止。相反,只需使用
TThread.CreateAnonymousThread(…).Start一次呼叫完成。我怀疑这里有误会。调用CheckTerminated时,您的目标是什么?简单的解决方案是不依赖于
同步
中的CheckTerminated,它应该只有最少的代码和非常短的执行时间。毕竟,这是线程背后的首要思想,保持主线程的响应性。如果您担心线程在
同步中终止,那么您需要重新考虑您的设计。这样的检查应该在实际线程本身的上下文中进行,而不是在
同步
(主线程)中进行。就我个人而言,我看不出任何人希望在
同步
中获得此信息的原因。查看页面,我认为它可以帮助您注意一点,保留对匿名线程的引用并期望使用它是非常危险的。一旦启动它,它就没有意义了,因为线程可能会在您想要使用它的时候终止。相反,只需使用
TThread.CreateAnonymousThread(…).Start一次呼叫完成。我怀疑这里有误会。调用CheckTerminated时,您的目标是什么?简单的解决方案是不依赖于
同步
中的CheckTerminated,它应该只有最少的代码和非常短的执行时间。毕竟,这是线程背后的首要思想,保持主线程的响应性。如果您担心线程在
同步中终止,那么您需要重新考虑您的设计。这样的检查应该在实际线程本身的上下文中进行,而不是在
同步
(主线程)中进行。就我个人而言,我看不出任何人想要在
同步中使用此信息的原因。但是,此信息受XE2保护,我无法访问它:(@Stephane您在问题中没有提到XE2。我已经为您添加了标记。根据经验,如果问题没有特定版本,则假定它是最新的当前版本。您最好只创建一个继承的
TThread
对象。尤其是如果您打算让它执行任何长时间运行的任务。@Stephane您可以使用访问器类从类外部访问类的受保护成员,例如
键入TThreadAccess=class(TThread)end;…如果TThreadAccess(FMyThread).Terminated then…
@Stephen我也这么想。CheckTerminated不会做您认为它会做的事情。您问题的解决方案不包括调用CheckTerminated。但是Terminated受XE2保护,我无法访问它:(@Stephane您在问题中没有提到XE2。我已经为您添加了标记。根据经验,如果问题没有特定版本,则假定它是最新的当前版本。您最好只创建一个继承的
TThread
对象。尤其是如果您打算让它执行任何长时间运行的任务。@Stephane您可以使用访问器类从类外部访问类的受保护成员,例如
键入TThreadAccess=class(TThread)end;…如果TThreadAccess(FMyThread).Terminated then…
@Stephen我也这么想。CheckTerminated不会做你认为它会做的事情。解决问题的方法不包括调用CheckTerminated。