5

未処理の例外処理に .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 をコンソールに出力しますが、これは私が期待するものではありません。

何か案は?

ありがとう。

4

1 に答える 1

6

ThreadAbortException をキャッチすることはできません。キャッチした後は常に再発生します。あなたの問題には2つの基本的な解決策があります。

最初の 1 つは、中止要求をリセットすることです。

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

2 つ目は、従来の例外処理を有効にしたときに発生する別の問題に対処することです。AppDomain.UnhandledException イベントは、致命的ではない例外に対しても発生するようになりました。次のように例外ハンドラを記述します。

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

最初の解決策をお勧めする必要があります。スレッドを終了させる未処理の例外がまったく痕跡を残さないようにすることは本当に望ましくありません。

于 2012-10-30T16:15:46.033 に答える