LegacyUnhandledExceptionPolicy不允许捕获(并吞下)ThreadAbortException?

时间:2012-10-30 14:18:56

标签: .net multithreading threadabortexception

我正在使用.NET 1.1兼容模式进行未处理的异常处理。问题是当LegacyUnhandledExceptionPolicy设置为“1”(这就是我想要的)时,我无法捕获并吞下ThreadAbortException。

示例代码:

App.config中:

<configuration>
   <runtime>
      <legacyUnhandledExceptionPolicy enabled="1"/>
   </runtime>
</configuration>

代码:

   class Program {

      static void Main(string[] args) {
         AppDomain.CurrentDomain.UnhandledException += _onBackgroundThreadCrash;
         var t = new Thread(_worker) { IsBackground = true };
         t.Start();
         Thread.Sleep(1000);
         t.Abort();
         Console.ReadLine();
      }

      private static void _worker() {
         try {
            while (true);
         } catch (ThreadAbortException) { 
            // expected thread exit, don't rethrow
         }
      }

      private static void _onBackgroundThreadCrash(object sender, UnhandledExceptionEventArgs e) {
         Console.WriteLine(e.ExceptionObject as Exception);
      }

   }

当遗留异常处理为“0”(OFF)时,上面的代码会按预期的方式吞下ThreadAbortException。

但是,当遗留异常处理为“1”时,上面的代码会将ThreadAbortException打印到控制台,这不是我所期望的。

有什么想法吗?

感谢。

1 个答案:

答案 0 :(得分:4)

你无法捕获ThreadAbortException,它总是在捕获后重新引发。您的问题有两种基本解决方案。

首先,您要重置中止请求:

catch (ThreadAbortException) {
    // expected thread abort request, reset it and exit thread
    Thread.ResetAbort();
}

第二个是解决启用遗留异常处理时发生的另一件事。现在还针对非致命异常引发AppDomain.UnhandledException事件。像这样编写你的异常处理程序:

private static void _onBackgroundThreadCrash(object sender, UnhandledExceptionEventArgs e) {
    if (e.IsTerminating) {
        Console.WriteLine(e.ExceptionObject as Exception);
    }
}

我不得不推荐第一个解决方案,你真的不希望终止线程的未处理异常根本不留下任何痕迹。