2

とてもシンプルなスレッドがあります。Threadオブジェクトが行うのは。だけですthrow new Exception();。これを行った理由は、アプリケーションの別のスレッドで例外が発生した場合に何が起こるかをテストする必要があったためです。「実際の」実行時例外を使用してこれをテストしましたが、問題は同じです。

スレッドを呼び出す前に行うことは次のとおりです。

AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
Application.Current.DispatcherUnhandledException += CurrentOnDispatcherUnhandledException;

//To handle exceptions in another thread
private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
    //Do nothing ignore exception
}

//To handle all exceptions in main thread
private static void CurrentOnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs dispatcherUnhandledExceptionEventArgs)
{
    dispatcherUnhandledExceptionEventArgs.Handled = true;
}

このスレッドが例外をスローすると、最初は正常にヒットCurrentDomainOnUnhandledExceptionし、次にヒットしませんCurrentOnDispatcherUnhandledException。直後にCurrentDomainOnUnhandledException、スタックはスレッドに戻り、そこで例外をスローして再度スローし、同じ行を実行します。これをやめることはありません。基本的には無限ループであり、その理由がわかりません。

UnhandledExceptionEventArgsには、設定するプロパティがありません。つまり、例外を処理したので、これが問題の一部であると確信しています。

何が間違っているのか、このスレッドでこのUnhandledExceptionをキャッチし、スレッドに実行を継続させる(推奨)か、スレッドを中止/強制終了して(非推奨)、新しい例外行の実行を継続しないようにする方法。

私はこれをデバッグとリリースでテストしました(リリースのデバッグ情報がnoneに設定されていることを確認しました)。これは両方のバージョンで引き続き発生し、例外は何度も発生し続けます。

事前のおかげで、私は困惑していて、なぜそれが行われるのかわかりません。

4

1 に答える 1

1

このスレッドが例外をスローすると、最初にCurrentDomainOnUnhandledExceptionが発生し、次にCurrentOnDispatcherUnhandledExceptionが発生しません。CurrentDomainOnUnhandledExceptionの直後スタックはスレッドに戻り、そこで例外をスローして再度スローし、同じ行を実行します。これをやめることはありません。基本的には無限ループであり、その理由がわかりません。

例外を処理したことはありません。そもそも障害が発生したのとまったく同じコードに戻っただけです。コードがこれを行うと言います:

i = 1 / 0;
foo(i);

そして、ゼロ除算エラーをキャッチしたとしましょう。しかし、ハンドラーでは、戻る以外に何もしません。さて、あなたは何が起こると思いますか?コードで致命的なエラーが発生し、それ以上の進行が不可能になり、修正するために何もしませんでした。どの値をi含める必要がありますか?!

基本的に、例外をスローするコードの設計の一部を除いて、例外をキャッチしようとしないでください。それは意味がありません、そしてあなたの外側の問題が何であれ、それをするための賢明な方法があるでしょう。

しかし、スレッドがひどく失敗した場合、そのプロセスはひどく失敗します。これがスレッドの性質です。分離はありません。検討:

  1. ロックを取得する
  2. 一部のオブジェクトを変更する
  3. ロックを解除する

手順2の途中で例外がスローされた場合はどうなりますか?例外ハンドラがロックを解放しない場合、ロックを取得しようとする次のスレッドは永久に待機します。例外ハンドラがロックを解放した場合、それを取得する次のスレッドは、部分的に変更され、おそらく一貫性のない状態にあるオブジェクトにアクセスします。したがって、例外ハンドラーは、例外がスローされたときに保持されていたロックを解放する前に何をすべきかについて、インテリジェントな決定を行い、例外をスローしたコードを理解する必要があります。

例外をキャッチする場合は、根本的な問題が何であるかを把握し、それを修復する必要があります。一般に、これを実行できるのは、例外をスローしたコードを完全に理解している場合のみです。破損している可能性のあるオブジェクトを修復する一般的な方法がないため、一般的な方法はありません。

では、CurrentDomainOnUnhandledExceptionのスレッドを強制終了して、例外のループを停止するにはどうすればよいですか?

一般的に、それはあなたがやりたいことではありません。そのスレッドがロックを保持している場合はどうなりますか?そのスレッドが解放する必要のあるメモリを割り当てた場合はどうなりますか?

この種の分離が必要な場合は、スレッドではなくプロセスを使用してください。

于 2012-09-01T10:07:22.377 に答える