Delphi如何检查TThread是否仍在运行?

11

我正在使用 TThread,我只需要找出线程是否仍在运行并在运行时间过长时终止应用程序。

例如:

我使用 TThread,只需查找线程是否仍在运行并且如果运行时间太长,则终止应用程序。

MyThread := TMyThread.Create;
MyThread .Resume;
MyThread.Terminate;

total := 0;
while MyThread.isRunning = true do // < i need something like this
begin
  // show message to user to wait a little longer we are still doing stuff
  sleep(1000);
  total := total + 1000;
  if total > 60000 then 
     exit;
  end;

Delphi可以实现这个吗?

1个回答

11
您的问题的直接答案是TThreadFinished属性。然而,我不建议使用它。它会导致你提出的那个相当讨厌的基于Sleep的循环。
有许多更干净的选项,包括至少以下几种:
  1. 使用 WaitFor 阻塞线程直到完成。这将阻塞调用线程,从而无法显示 UI 或响应用户。
  2. 在循环中使用 MsgWaitForMultipleObjects,传递线程句柄。这允许您等待线程完成,但也可以服务 UI。
  3. OnTerminate 事件实现事件处理程序。这允许您以事件驱动的方式被通知线程的终止。

我建议您使用其中一种选项,而不是自己编写基于 Sleep 的循环。根据我的经验,选项 3 通常会导致最干净的代码。但是,如果不了解所有要求,很难给出严格的建议。只有您拥有这些知识。


没有isRunning,好难过。等待阻塞这样做就违背了线程的初衷。我避免使用MsgWaitForMultipleObjects,因为在COM应用程序中很容易导致意外问题。所以我想我只能使用OnTerminate,但这并不好,因为需要添加大量的代码来检查所有线程是否已完成。 - uacaman
我没有TThread.Finished,刚发现OnTerminate是无用的。http://docwiki.embarcadero.com/Libraries/XE2/en/System.Classes.TThread.OnTerminate上的文档说OnTerminate在Execute之后和destroy之前被调用,但这是不正确的。当您尝试释放线程时,将调用OnTerminate,但Thread.Free会调用WaitFor阻止主线程。此行为防止使用OnTerminate设置标志以指示线程终止,因为它将一直阻塞,直到处理完成。 - uacaman
1
你为什么要调用 Free 函数?我以为你想等到它完成后再释放资源。Finished 的实现很简单,你可以在线程类中添加一个布尔值,在 Execute 函数退出时将其设置为 true。或者其他类似的方法。 - David Heffernan
2
我无法理解那个注释。抱歉。 - David Heffernan
简单来说,当您在主线程上使用onTerminate时,它正在忙于执行您的任务。只有当您将控制权释放回操作系统时,onTerminate才会触发。这使得在主线程上使用onTerminate变得不可能。 - uacaman
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接