Application.ThreadExceptionとAppDomain.CurrentDomain.UnhandledExceptionの違いは何ですか?


回答:


98

Application.ThreadExceptionはWindowsフォームに固有です。Winformsは、Windowsから送信されたメッセージに応答してイベントハンドラーを実行します。たとえば、Clickイベントは、あなたがそれらを知っていると確信しています。そのようなイベントハンドラーが例外をスローする場合、その例外をキャッチするWinformsメッセージループ内にバックストップがあります。

そのバックストップはApplication.ThreadExceptionイベントを発生させます。オーバーライドしない場合、ユーザーはThreadExceptionDialogを取得します。これにより、彼は例外を無視してプログラムを実行し続けることができます。ところで、素晴らしいアイデアではありません。

この動作を無効にするには、Program.csのMain()メソッドでApplication.SetUnhandledExceptionMode()を呼び出します。そのバックストップがないと、スレッドが未処理の例外で停止したときにAppDomain.UnhandledExceptionが発生してプログラムが終了するという通常のことが起こります。

Fwiw:「ThreadException」は非常に悪い名前の選択でした。スレッドとは関係ありません。


そして、WinFormsアプリケーションがの発生時にクラッシュしないようにする方法Application.ThreadException。私は小さな[ C#]コードでこの[ここ ]に質問を投げかけました。
Mahesha999 14

2
winformsが単一のスレッドにバインドされていることを考えると、常にアプリケーションスレッドの例外としてそれを読みます。
Gusdor 2014

36

ソースから:

Windowsフォームを使用するアプリケーションでは、メインアプリケーションスレッドで未処理の例外が発生すると、Application.ThreadException イベントが発生します。このイベントが処理される場合、デフォルトの動作では、アプリケーションは不明な状態のままですが、未処理の例外によってアプリケーションが終了することはありません。その場合、UnhandledException イベントは発生しません。この動作は、アプリケーション構成ファイルを使用するか、Application.SetUnhandledExceptionModeメソッドを使用し てモードを変更しUnhandledExceptionMode.ThrowExceptionThreadException イベントハンドラーがフックされる前に変更 できます。これは、メインアプリケーションスレッドにのみ適用されます。このUnhandledException イベントは、他のスレッドでスローされた未処理の例外に対して発生します。

以降ではVisual Studio 2005のVisual Basicのアプリケーションフレームワークは、メインアプリケーションスレッドで未処理の例外のために別のイベントを提供します- WindowsFormsApplicationBase.UnhandledException。このイベントには、AppDomain.UnhandledExceptionで使用されるイベント引数オブジェクトと同じ名前で、プロパティが異なるイベント引数オブジェクトがあります。特に、このイベント引数オブジェクトにはExitApplication、未処理の例外を無視して(そしてアプリケーションを不明な状態のままにして)、アプリケーションの実行を継続できるプロパティがあります。その場合、AppDomain.UnhandledExceptionイベントは発生しません。

Application.ThreadExceptionキャッチされ、アプリケーションが続行する可能性があります(一般的には良いアイデアではありませんが、定期的に実行するようなアプリケーションの場合、これは良い解決策です)。

Windowsフォームによって作成および所有されていないスレッドで発生する例外をキャッチするには、を使用しAppDomain.UnhandledExceptionます。これにより、アプリケーションは、システムのデフォルトハンドラーがユーザーに例外を報告してアプリケーションを終了する前に、例外に関する情報をログに記録できます。
この例外の処理は、アプリケーションの終了を妨げません。
実行できる最大値(例外が処理されない場合、プログラムデータは破損する可能性があります)は、後で回復するためにプログラムデータを保存することです。その後、アプリケーションドメインがアンロードされ、アプリケーションが終了します。

以降では、.NET 4のプロセスの壊れた状態というイベントハンドラがセキュリティ重要であり、持っていない限り、このイベントは、そのようなスタックオーバーフローまたはアクセス違反として、例外を発生しませんHandleProcessCorruptedStateExceptionsAttribute 属性を。

詳細については、MSDNを参照してください。


18

OK-私の目の前にそれがありました、msdnからのこのコードのコードはかなり自明です:

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new 
        ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}

3
これは、serhioが言う他の回答とは対照的です。UnhandledExceptionMode.ThrowExceptionは、ThreadExceptionイベントハンドラーがフックされる前に設定する必要があります。順序が本当に重要であるかどうかわからない...
Davide Piras

@DavidePirasはい、そしてもっと曖昧なものがあります。SetUnhandledExceptionは、私の場合には何の違いもないようです。
nawfal 2014年

0

さてThreadException問題は、スレッドの問題が原因で発生し、Unhandled Exceptionコードが処理されない例外をスローした場合に発生します。

2番目の原因となる簡単な方法は、try ... catchブロックなしでアプリを作成し、例外をスローすることです。

保険が必要な場合は両方を処理できますが、exceptions正しくキャプチャして処理する場合はUnhandledException、すべてをキャッチするようなハンドラーは必要ありません。


感謝-私があまり明確ではなかったのは、UnhandledExceptionを処理する場合にThreadExceptionもキャッチすることでした-これはそうではないようです
JohnIdol
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.