【问题标题】:Terminate worker thread which is running message loop in C#终止在 C# 中运行消息循环的工作线程
【发布时间】:2013-01-24 12:38:01
【问题描述】:

我在工作线程中使用了SetWindowHookEx() Windows API 并接收操作系统通知,我使用Application.Run() 运行了应用程序消息泵。

现在,我想停止消息泵并退出工作线程,但是我没有很好的方法来终止线程。

另外,我正在使用Thread.Abort() 方法来终止线程,但不推荐使用这种方法来优雅地终止线程。

谁能建议如何从 UI 线程或主窗体优雅地关闭消息泵,以便工作线程自动返回并退出?

【问题讨论】:

  • 您可以将 BackgroundWorker 与 SupportsCancellation 一起使用吗?
  • 如果您是基于 .NET4 的,我建议您查看 System.Threading.Tasks 中的 Task 对象。它有一个取消令牌,您可以使用它来中止操作。
  • 您的应用程序是否同时运行两个消息泵?如果是这样……那可能很糟糕。您应该首先避免这样做,并重复使用单个泵。
  • Thread.Abort() 不再是“£@$ 曾经的可怕之处。它现在不是停止死去的东西,而是引发一个异常,可以用来优雅地释放任何锁和必要时提供资源

标签: c# .net windows winforms


【解决方案1】:

如果您优雅地处理 Thread.Abort() 将在工作线程中引起的 ThreadAbortException,那么中止线程并没有什么不优雅的。

【讨论】:

  • 这是错误的。当您中止任意方法时,可能会发生很多 非常 不好的事情,包括未清理非托管资源,如果您调用的代码在长循环中捕获所有异常,则实际上并未中止,等等。如果您只是中止运行您查看过的一组固定代码的线程,您可以确定这一切都不会发生,但这里不是这种情况,因为基本上任何东西都可以放入该消息泵中。跨度>
【解决方案2】:

不要使用无参数的Application.Run,而是使用接受ApplicationContext 的重载。

应用程序上下文有一个ExitThread 方法,可以优雅地结束消息循环。

【讨论】:

  • 我的回答好像反了?
【解决方案3】:

为什么不直接从另一个线程调用 Application.Exit?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-16
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    相关资源
    最近更新 更多