web-dev-qa-db-ja.com

.NETアプリですべての例外/クラッシュをキャッチする方法

可能性のある複製:
。NET-「すべての例外ハンドラをキャッチ」を実装する最良の方法は何ですか

クラッシュし、ユーザーにメッセージを表示する.NETコンソールアプリがあります。すべてのコードはtry{<code>} catch(Exception e){<stuff>}ブロックにありますが、それでもエラーが表示されることがあります。

Win32アプリでは、さまざまな例外ハンドラーをインストールすることにより、考えられるすべての例外/クラッシュをキャプチャできます。

/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler

可能性のあるすべてのエラーケースを処理/ログ/クワイエットできるように、.NETの世界で同等のものは何ですか?

39
DougN

他の人が投稿したものとは反対に、すべての例外をキャッチするのは間違っていません。重要なことは、それらすべてを適切に処理することです。スタックオーバーフローまたはメモリ不足の状態がある場合、アプリはそれらのためにシャットダウンする必要があります。また、OOM条件により、例外ハンドラーが正しく実行できなくなる可能性があることに注意してください。たとえば、例外ハンドラが例外メッセージを含むダイアログを表示する場合、メモリが不足していると、ダイアログを表示するのに十分な量が残っていない可能性があります。ログに記録してすぐにシャットダウンするのが最善です。

他の人が述べたように、UnhandledExceptionイベントとThreadExceptionイベントがあります。これらのイベントは、他の方法では見落とされる可能性のあるコレクション例外に対して処理できます。次に、メインループの周りに例外ハンドラをスローします(winformsアプリを想定)。

また、メモリ不足状態に対してOutOfMemoryExceptionsが常にスローされるわけではないことに注意する必要があります。 OOM条件は、コード内またはフレームワーク内のあらゆる種類の例外をトリガーできます。例外は、実際の基礎条件がメモリ不足であるという事実とは必ずしも関係がありません。根本的な原因が実際にメモリ不足である場合、InvalidOperationExceptionまたはArgumentExceptionを頻繁に見ました。

27
Pete Davis

AppDomain.UnhandledExceptionイベントにイベントハンドラーを追加できます。イベントハンドラーは、例外がスローされてキャッチされなかったときに呼び出されます。

43
Juanma

ホストJeff Atwoodによるcodeprojectのこの記事 が必要です。未処理の例外をキャッチするためのコードと、クラッシュに関する情報をユーザーに表示するための最良の方法が含まれています。

11
Ricardo Amores

Global.asaxクラスは最後の防衛線です。見る:

protected void Application_Error(Object sender, EventArgs e)

方法

10
Drejc

いくつかの例外はキャッチするのが危険であることに注意してください-またはほとんどキャッチできない、

  • OutOfMemoryException:catchハンドラーで行うことはすべて(CLRの管理側または非管理側で)メモリを割り当て、別のOOMをトリガーする可能性があります
  • StackOverflowException:CLRがそれを十分に早く検出したかどうかに応じて、通知される場合があります。最悪のシナリオでは、単にプロセスを強制終了します。
6
Peli

all例外を適切に処理する計画なしでキャッチすることは確かに悪い習慣ですが、アプリケーションは何らかの優雅な方法で失敗するはずだと思います。クラッシュによってユーザーが死ぬことはありません。少なくともエラーの説明、テクニカルサポートに報告する情報、および理想的にはアプリケーションを閉じて再起動するボタンを表示する必要があります。理想的な世界では、アプリケーションはユーザーデータをディスクにダンプし、それを回復しようとするはずです(しかし、これはあまりにも多くの質問をしていることがわかります)。

とにかく、私は通常使用します:

AppDomain.CurrentDomain.UnhandledException
4
Dario Solera

AppDomain.CurrentDomain.UnhandledExceptionを使用してイベントを取得できます。

4
Mendelt

Application.ThreadExceptionイベントを使用することもできます。

COMベースのアプリケーション内で実行する.NETアプリを開発していたとき;この場合、AppDomain.CurrentDomain.UnhandledExceptionは機能しなかったため、このイベントは非常に役立ちました。

3
petr k.

例外をすべてキャッチするのではなく、それらをユーザーに表示する方がよいと思います。これは、実際に処理できる例外のみをキャッチする必要があるためです。プログラムを停止させるが、それでもキャッチする例外が発生した場合、これはより深刻な問題を引き起こす可能性があります。 FAQ:FxCopがcatch(Exception)に対して警告するのはなぜですか? も読んでください。

1
hangy

これらの未処理の例外をキャッチすると、アプリケーションのセキュリティ要件が変わる可能性があることに注意してください。アプリケーションは、特定のコンテキストで正常に実行を停止する場合があります(ネットワーク共有などから実行される場合)。徹底的にテストしてください。

1
Johnny Bravado

appDomain.CurrentDomain.UnhandledException Application.ThreadExceptionの両方を使用しても問題ありません

ただし、セカンダリスレッドの例外はこれらのハンドラーによってキャッチされないことに注意してください。必要に応じて、セカンダリスレッドに SafeThread を使用します

0
Steven A. Lowe