【问题标题】:how to catch ThreadAbort?如何捕捉线程中止?
【发布时间】:2011-08-31 00:16:49
【问题描述】:

我有一个函数,我调用 thread.abort 来杀死一个线程。我知道这不是最佳实践,但是我在 dll 中调用一个函数,该函数基本上在该函数中有一个无限循环,所以我可以终止线程的唯一方法是调用线程中止。我可以调用 thread.join,但我的 gui 会卡住。我在表单应用程序和该线程中都进行了捕获,但是当我调用 thread.abort 函数时,抛出了一个异常,该异常被其中一个地方的 try 块捕获,但我的应用程序仍然崩溃。

处理 threadAbort 的正确方法是什么,以免我的应用程序崩溃。

【问题讨论】:

  • 您的应用程序是如何崩溃的?抛出的这个其他异常的堆栈跟踪是什么?这个其他 dll 是托管的还是非托管的(是的,它很重要,实际上是至关重要的信息)?

标签: c# multithreading exception-handling


【解决方案1】:

您的应用程序正在崩溃,因为 ThreadAbortException 在处理它的任何 catch 块的末尾自动重新抛出。为防止它被重新抛出,您需要致电Thread.ResetAbort()

try {
  ...
} catch (ThreadAbortException) {
  Thread.ResetAbort();
}

注意:我建议您找到另一种方法来摆脱这种方法。中止线程是非常危险的,应该只是最后的一种机制。将取消标记传递给线程或使用共享标志退出无限循环会更安全。

【讨论】:

    【解决方案2】:

    不要使用Thread.Abort(),通知线程停止。类似的东西

    private volatile _keepRunning = true;
    
    public void DoWork()
    {
        while(_keepRunning)
        {
        }
    }
    
    public void Abort()
    {
        _keepRunning = false;
    }
    

    您可以更花哨地使用ManualResetEvents 来更快地发出结束信号,并且仍然使用连接,但基本概念就在那里。我经常在我们的应用程序中使用它,效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 2017-10-26
      • 1970-01-01
      • 2013-08-09
      • 2018-03-18
      • 2011-12-30
      • 1970-01-01
      相关资源
      最近更新 更多