LegacyUnhandledExceptionPolicy doesn't allow to catch (and swallow) ThreadAbortException?

情到浓时终转凉″ 提交于 2019-12-23 15:52:09

问题


I'm using .NET 1.1 compability mode for unhandled exception handling. The problem is that when LegacyUnhandledExceptionPolicy is set to "1" (which is what I want), I cannot catch and swallow ThreadAbortException.

Example code:

App.config:

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

Code:

   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);
      }

   }

When legacy exceptions handling is "0" (OFF), the above code swallows ThreadAbortException queitly, as expected.

But, when legacy exceptions handling is "1" the above code prints ThreadAbortException to console, which is not what I expect.

Any ideas?

Thanks.


回答1:


You cannot catch a ThreadAbortException, it is always re-raised after catching it. There are two basic solutions to your problem.

First one is that you reset the abort request:

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

Second one is to address the other thing that happens when you enable legacy exception handling. The AppDomain.UnhandledException event is now also raised for non-fatal exceptions. Write your exception handler like this:

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

I'd have to recommend the first solution, you really don't want unhandled exceptions that terminate a thread to leave no trace at all.



来源:https://stackoverflow.com/questions/13140961/legacyunhandledexceptionpolicy-doesnt-allow-to-catch-and-swallow-threadaborte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!