【问题标题】:Thread not terminated while application is terminated under Delphi在 Delphi 下终止应用程序时线程未终止
【发布时间】:2013-04-22 08:25:53
【问题描述】:

假设我有一个线程在应用程序终止时仍在运行

(此线程无法终止,因为它正在等待 Windows api 调用返回 这可能很长......)

如果应用程序关闭,线程会发生什么?

它会引发异常(我在 Delphi 下)?

【问题讨论】:

  • 那么,您的应用程序是如何终止的?有不止一种方法可以做到这一点。
  • application.terminate;
  • 您的工作线程实际使用的是哪个 Win32 API 函数?很有可能它提供了一种取消函数的方法,因此您的工作线程可以在请求时正确终止自身。主线程应该在退出进程之前终止工作线程。

标签: windows multithreading delphi


【解决方案1】:

我会说例外是非常合理的。当您调用Application.Terminate 时,这将导致以下事件序列:

  1. 致电PostQuitMessage
  2. Application.Terminated 被设置为 True
  3. Application.Run 回来了。
  4. System.Halt 被调用。
  5. 运行退出程序,特别是DoneApplication,它将拆除Application 及其拥有的所有组件。嗯,最好希望你的线程不会访问 Application 拥有的任何东西。
  6. FinalizeUnits 被调用。哦哦。内存管理器已关闭,此外还有更多。
  7. ExitProcess 被调用。现在你的线程被杀死了。

您的线程将继续运行,直到调用ExitProcess。如果它执行任何会受到DoneApplicationFinalizeUnits 调用影响的代码,那么您应该会遇到问题。

【讨论】:

  • 是的,通常是因为表单以及它们使用的内存在操作系统有机会在步骤 7 中停止所有线程之前消失了。如果您构建应用程序以便线程读/写直接针对表单中的数据,往往会引发“216”或“217”异常。很长一段时间以来,我一直通过仅通过不属于表单并且通常从未显式释放的 PostMessaging 对象与表单通信来避免此问题。
  • 我的线程不与表单通信。它只会删除网络驱动器上的一些文件(网络驱动器可能需要很长时间才能访问......)
  • @user382591 - 那么你应该没问题。如果您的线程卡在 API 调用上,无论是阻塞还是读取/写入在步骤 7 之前未释放的数据,都不会引发 IME 异常。
  • 在所有进程线程停止后,操作系统将在步骤 7 中关闭网络驱动器的句柄,因此,您应该没问题。
  • 如果它使用 Delphi 内存管理器,那么你就有麻烦了。这在第 6 步中进行。
猜你喜欢
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
相关资源
最近更新 更多