【问题标题】:How can a worker thread end the application?工作线程如何结束应用程序?
【发布时间】:2021-03-15 22:43:19
【问题描述】:

我似乎遇到了工作线程知道关闭应用程序的挑战,但PostQuitMessage()Application.Terminate() 似乎都不起作用。应用程序只是没有退出,没有错误。

我是否必须设置一个标志才能从主线程调用其中一个,或者还有其他技巧吗?

线程检查更新的版本并调用更新程序来替换.exe(一旦它不再被锁定)。调用更新程序后,需要退出应用程序。

【问题讨论】:

  • 你显然没有尝试ExitProcess(0)。不过,您确定线程应该是终止应用程序的线程吗? PostQuitMessage 不起作用,因为您从错误的线程发布它:“PostQuitMessage 函数将 WM_QUIT 消息发送到线程的消息队列并立即返回”。 Application.Terminate 不起作用,因为它基于 PostQuitMessage。仍然:正确的解决方案可能是重新设计,以便主线程确定何时退出。
  • 我已经添加了关于为什么这个线程“需要”退出的信息......:-/
  • (当然这个辅助线程可能会要求主线程退出,然后主线程才能真正退出。)

标签: multithreading delphi


【解决方案1】:

PostQuitMessage()WM_QUIT 消息发布到调用线程的消息队列。 Application.Terminate() 使用 PostQuitMessage()。这就是为什么两者都不适用于您的情况,因为您在错误的线程上下文中调用它们。

所以,你可以:

  • 标记主线程以尽早调用PostQuitMessage()/Application.Terminate(),例如TThread.Queue()

    TThread.Queue(nil, Application.Terminate);

  • 将您自己的WM_QUIT 消息发布到主线程或Application 窗口,即:

    PostThreadMessage(MainThreadID, WM_QUIT, 0, 0);

    PostMessage(Application.Handle, WM_QUIT, 0, 0);

  • WM_CLOSE 消息发布到您的MainForm 窗口(如果有)1,因为关闭MainForm 将终止应用程序,即:

    PostMessage(Application.MainForm.Handle, WM_CLOSE, 0, 0);

    1:小心这个! TWinControl.Handle 属性不是线程安全的。如果您在主线程正在(重新)创建窗口的过程中在工作线程中读取 MainForm 的 Handle 属性,则可能会发生不好的事情!

【讨论】:

    【解决方案2】:

    雷米有一个很好的答案。

    如果您使用的是 Delphi 线程(您的线程派生自 TThread),那么您可以使用线程的 Synchronize 方法在主线程,然后在该例程(由主线程运行)中,您可以调用 Application.Terminate

    见:http://docwiki.embarcadero.com/Libraries/Sydney/en/System.Classes.TThread.Synchronize

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-05
      • 2014-08-04
      • 2020-08-28
      相关资源
      最近更新 更多