delphi - 销毁 Thread 对象的正确方法

标签 delphi destructor tthread

这个问题看似微不足道,但我希望你不要忽视它。
在销毁 TThread 对象之前,通常需要等待调用 TThread.Execute() 方法的线程完成,因为只有这样我们才能确定,例如,在类的析构函数中销毁的对象不再被访问。因此需要调用Terminate设置线程必须检查的Termerated标志来确定是否退出,然后调用WaitFor()方法。

因为线程可能被挂起,所以我认为最好在调用WaitFor之前恢复它,否则调用线程会死锁。而且因为线程可以被挂起多次,所以它应该恢复相同的次数,对吧?

while Suspended do
  Resume;

如果线程是挂起创建的,我们不必担心当我们恢复线程只是为了终止它时会调用 TThread.Execute() 方法 - 它不会(如果我错了,请纠正我) )。

我所说的建议对每个要释放的 TThread 对象使用以下代码行:

MyThread.Terminate;
while MyThread.Suspended do
  MyThread.Resume;
MyThread.WaitFor;
MyThread.Free;

不幸的是,当我们销毁创建了多个线程的应用程序时,为每个被销毁的 TThread 对象编写这样一段代码是不必要的,这会使代码变得非常长,甚至可能不透明。

因此我得出的结论是,所有这些都可以放入 TThread 类的重写析构函数中,因此调用 MyThread.Free (或 MyThread.Terminate,如果设置了 MyThread.FreeOnTerminate )就足够了,而无需关心被销毁的对象是否是TThread对象:

destructor TMyThread.Destroy;
begin
  //if FreeOnTerminate, the calling thread cannot wait for itself
  if GetCurrentThreadId <> ThreadId then
  begin
    Terminate;
    while Suspended do
      Resume;
    WaitFor;
  end;

  {free all objects created in this class}

  inherited Destroy;
end;

请原谅我问这么基本的问题。然而,我想了解您对这种销毁 TThread 对象的方式(我希望是一种通用方式)的看法。我问这个问题是因为我从同事的代码中了解到,他们通常使用第一个代码示例来销毁此类对象,但他们从未用于检查正在等待的线程是否没有被挂起,我认为如果线程有一点危险可能会在代码中的某个地方暂停。因此,我试图找到一种通用的方法来销毁此类的对象,从而使代码更清晰、更安全。我希望我没有让事情变得更糟 - 你觉得怎么样?

感谢您提前提出的建议。

最佳答案

您的建议的大部分内容已经在 TThread.Destroy 析构函数中执行,并且调用 TMyThread.free 将执行您的建议。要清理线程类拥有的任何对象,您可以在 OnTerminate 事件中执行该操作,该事件将作为线程关闭逻辑的一部分被调用。

关于delphi - 销毁 Thread 对象的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1089482/

相关文章:

与构造函数/析构函数定义相关的c++编译错误

c++ - 如何正确删除C++中的指针?

delphi - 如何捕获突然破坏的TThread

delphi - 组件编辑器可以在多个组件上执行吗?

delphi - 如何将 TFileStream 与 FILE_SHARE_DELETE 一起使用?

德尔福ADO : Locate with dataset filter on bug

c++ - 派生类销毁后使用基类成员

multithreading - 从线程内部实例化一个降序线程是否安全?

macos - Mac 上的 Delphi XE7(up1) 中的 TOpendialog 有问题?