31

私は.NET1.1アプリケーションを保守しており、私が担当していることの1つは、ユーザーに不適切なエラー通知が表示されないようにすることです。

Application.ThreadExceptionとにハンドラーを追加しましたAppDomain.CurrentDomain.UnhandledException。これらは呼び出されます。私の問題は、標準のCLRエラーダイアログがまだ表示されていることです(例外ハンドラーが呼び出される前)。

ジェフはここここで彼のブログでこの問題について話します。しかし、解決策はありません。では、キャッチされない例外を処理し、わかりやすいダイアログボックスを表示するための.NET 1.1の標準的な方法は何ですか?

ジェフが提供したリンクには、必要なことを行う方法に関する最も完全な情報が含まれているため、ジェフの回答は正解としてマークされました。

4

6 に答える 6

13

ああ、Windowsフォームでは、間違いなくそれを機能させることができるはずです。注意しなければならないのは、さまざまなスレッドで発生していることだけです。

ここに古いCodeProjectの記事があります。

ユーザーフレンドリーな例外処理

于 2008-08-04T04:31:02.557 に答える
5

AppDomain.UnhandledExceptionイベントであり、グローバルな例外ハンドラーではありません。これは、発生するまでに、アプリケーションはすでにドレインに向かっていることを意味し、クリーンアップとエラー ログを実行する以外に、それに対してできることは何もありません。

舞台裏で起こったことは次のとおりです。フレームワークは例外を検出し、コール スタックを一番上まで移動しましたが、エラーから回復するハンドラーが見つからなかったため、安全に実行を継続できるかどうかを判断できませんでした。そのため、シャットダウン シーケンスを開始し、あなたへの礼儀としてこのイベントを起動しました。これは、メイン スレッドで例外が処理されないままになっている場合に発生します。

この種のエラーに対する単一の解決策はありません。このエラーが発生するすべての場所の上流に実際の例外ハンドラー (catch ブロック) を配置し、(たとえば) 単純に報告して続行することが安全かどうかを判断するグローバル ハンドラー メソッド/クラスに転送する必要があります。例外の種類および/または内容。

編集: Windows に組み込まれているエラー報告メカニズムを無効にする (= ハックする) ことができるため、アプリがダウンしたときに必須の「クラッシュ アンド バーン」ダイアログが表示されません。ただし、これは自分のアプリケーションだけでなく、システム内のすべてのアプリケーションに対して有効になります。

于 2008-08-04T10:20:01.260 に答える
5

.NET 1.x Windows フォーム アプリケーションでのハンドルされない例外の動作は、次のものに依存します。

  • 例外をスローしたスレッドのタイプ
  • ウィンドウ メッセージの処理中に発生したかどうか
  • デバッガーがプロセスにアタッチされたかどうか
  • DbgJitDebugLaunchSetting レジストリ設定
  • App.Config の jitDebugging フラグ
  • Windows フォームの例外ハンドラーをオーバーライドしたかどうか
  • CLR の例外イベントを処理したかどうか
  • 月の満ち欠け

未処理の例外の既定の動作は次のとおりです。

  • ウィンドウ メッセージをポンピングするときにメイン スレッドで例外が発生した場合は、Windows フォームの例外ハンドラーによってインターセプトされます。
  • ウィンドウ メッセージのポンピング時にメイン スレッドで例外が発生した場合、Windows フォームの例外ハンドラーによってインターセプトされない限り、アプリ プロセスは終了します。
  • 手動、スレッド プール、またはファイナライザー スレッドで例外が発生した場合、その例外は CLR によって取り込まれます。

未処理の例外の連絡先は次のとおりです。

  • Windows フォームの例外ハンドラー。
  • JIT デバッグ レジストリ スイッチ DbgJitDebugLaunchSetting。
  • CLR 未処理の例外イベント。

Windows フォームの組み込みの例外処理は、既定で次のことを行います。

  • 次の場合に未処理の例外をキャッチします。
    • 例外はメインスレッドにあり、デバッガーは接続されていません。
    • ウィンドウ メッセージの処理中に例外が発生します。
    • App.Config で jitDebugging = false。
  • ユーザーにダイアログを表示し、アプリの終了を防ぎます。

で jitDebugging = true を設定することにより、後者の動作を無効にすることができますApp.Config。ただし、これがアプリの終了を止める最後のチャンスになる可能性があることを忘れないでください。したがって、未処理の例外をキャッチする次のステップは、イベント Application.ThreadException を登録することです。次に例を示します。

Application.ThreadException += new
Threading.ThreadExceptionHandler(CatchFormsExceptions);

HKEY_LOCAL_MACHINE\Software.NetFramework の下のレジストリ設定 DbgJitDebugLaunchSetting に注意してください。これには、私が認識している 3 つの値のいずれかがあります。

  • 0: 「デバッグまたは終了」を求めるユーザー ダイアログを表示します。
  • 1: CLR が処理できるように例外を通過させます。
  • 2: DbgManagedDebugger レジストリ キーで指定されたデバッガーを起動します。

Visual Studio で、メニューの[ツール] → [オプション] → [デバッグ] → [JIT ] に移動して、このキーを 0 または 2 に設定します。ただし、通常、エンド ユーザーのマシンでは値 1 が最適です。このレジストリ キーは、CLR 未処理の例外イベントの前に実行されることに注意してください。

この最後のイベントは、未処理の例外をログに記録する最後のチャンスです。それは、Finally ブロックが実行される前にトリガーされます。このイベントは次のようにインターセプトできます。

AppDomain.CurrentDomain.UnhandledException += new
System.UnhandledExceptionEventHandler(CatchClrExceptions);
于 2008-09-20T15:52:49.377 に答える
3

これはコンソールアプリケーションですか、それともWindowsフォームアプリケーションですか?.NET 1.1コンソールアプリケーションの場合、残念ながら、これは設計によるものです。これは、参照した2番目のブログ投稿のMSFT開発者によって確認されています。

ところで、私の1.1マシンでは、MSDNの例に期待どおりの出力があります。デバッガーを接続する(または接続しない)まで、2行目が表示されないだけです。v2では、デバッガーが接続する前にUnhandledExceptionイベントが発生するように変更しました。これは、ほとんどの人が期待していることのようです。

.NET 2.0の方が優れているようですが(よかったです)、正直なところ、戻って確認する時間がありませんでした。

于 2008-08-04T02:45:07.717 に答える
1

これはWindowsフォームアプリケーションです。Application.ThreadExceptionによってキャッチされた例外は正常に機能し、醜い.NET例外ボックスが表示されません(OK終了Cancelする、デバッグする、誰がそれを思いついたのか??)。

私はそれによって捕らえられなかったいくつかの例外を受け取り、問題を引き起こしていたAppDomain.UnhandledExceptionイベントに行くことになりました。私はそれらの例外のほとんどを捕らえたと思います、そして私は今それらを私たちの素敵なエラーボックスに表示しています。

したがって、Application.ThreadExceptionハンドラーによって例外がキャッチされない原因となる他の状況がないことを期待する必要があります。

于 2008-08-04T02:54:15.683 に答える