AppDomain.UnhandledException イベント

定義

例外がキャッチされない場合に発生します。

public:
 event UnhandledExceptionEventHandler ^ UnhandledException;
public:
 virtual event UnhandledExceptionEventHandler ^ UnhandledException;
public event UnhandledExceptionEventHandler? UnhandledException;
public event UnhandledExceptionEventHandler UnhandledException;
[add: System.Security.SecurityCritical]
[remove: System.Security.SecurityCritical]
public event UnhandledExceptionEventHandler UnhandledException;
member this.UnhandledException : UnhandledExceptionEventHandler 
[<add: System.Security.SecurityCritical>]
[<remove: System.Security.SecurityCritical>]
member this.UnhandledException : UnhandledExceptionEventHandler 
Public Custom Event UnhandledException As UnhandledExceptionEventHandler 

イベントの種類

UnhandledExceptionEventHandler

実装

属性

UnhandledExceptionイベントの例を次に示します。 既定のアプリケーション ドメインでハンドルされない例外がスローされるたびに呼び出されるイベント ハンドラー MyHandlerを定義します。 その後、2 つの例外がスローされます。 1 つ目は try/catch ブロックによって処理されます。 2 つ目は未処理で、アプリケーションが終了する MyHandle 前にルーチンを呼び出します。

// The example should be compiled with the /clr:pure compiler option.
using namespace System;
using namespace System::Security::Permissions;

public ref class Example
{


private:
   static void MyHandler(Object^ sender, UnhandledExceptionEventArgs^ args)
   {
      Exception^ e = dynamic_cast<Exception^>(args->ExceptionObject);
      Console::WriteLine( "MyHandler caught : {0}", e->Message );
      Console::WriteLine("Runtime terminating: {0}", args->IsTerminating);
   }
   
public: 
   [SecurityPermissionAttribute( SecurityAction::Demand, ControlAppDomain = true )]
   static void Main()
   {
      AppDomain^ currentDomain = AppDomain::CurrentDomain;
      currentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(Example::MyHandler);
      try
      {
         throw gcnew Exception("1");
      }
      catch (Exception^ e) 
      {
         Console::WriteLine( "Catch clause caught : {0}\n", e->Message );
      }

      throw gcnew Exception("2");
   }
};

void main()
{
   Example::Main();
}   
// The example displays the following output:
//       Catch clause caught : 1
//       
//       MyHandler caught : 2
//       Runtime terminating: True
//       
//       Unhandled Exception: System.Exception: 2
//          at Example.Main()
//          at mainCRTStartup(String[] arguments)
using System;

public class Example
{
   public static void Main()
   {
      AppDomain currentDomain = AppDomain.CurrentDomain;
      currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);

      try {
         throw new Exception("1");
      } catch (Exception e) {
         Console.WriteLine("Catch clause caught : {0} \n", e.Message);
      }

      throw new Exception("2");
   }

   static void MyHandler(object sender, UnhandledExceptionEventArgs args)
   {
      Exception e = (Exception) args.ExceptionObject;
      Console.WriteLine("MyHandler caught : " + e.Message);
      Console.WriteLine("Runtime terminating: {0}", args.IsTerminating);
   }
}
// The example displays the following output:
//       Catch clause caught : 1
//
//       MyHandler caught : 2
//       Runtime terminating: True
//
//       Unhandled Exception: System.Exception: 2
//          at Example.Main()
open System
open System.Security.Permissions

let myHandler _ (args: UnhandledExceptionEventArgs) =
    let e = args.ExceptionObject :?> Exception
    printfn $"MyHandler caught : {e.Message}"
    printfn $"Runtime terminating: {args.IsTerminating}"

[<EntryPoint>]
let main _ =
    let currentDomain = AppDomain.CurrentDomain
    currentDomain.UnhandledException.AddHandler(UnhandledExceptionEventHandler myHandler)

    try
        failwith "1"
    with e ->
        printfn $"Catch clause caught : {e.Message} \n"

    failwith "2"

// The example displays the following output:
//       Catch clause caught : 1
//
//       MyHandler caught : 2
//       Runtime terminating: True
//
//       Unhandled Exception: System.Exception: 2
//          at Example.main()
Module Example
   Sub Main()
      Dim currentDomain As AppDomain = AppDomain.CurrentDomain
      AddHandler currentDomain.UnhandledException, AddressOf MyHandler
      
      Try
         Throw New Exception("1")
      Catch e As Exception
         Console.WriteLine("Catch clause caught : " + e.Message)
         Console.WriteLine()
      End Try
      
      Throw New Exception("2")
   End Sub
   
   Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
      Dim e As Exception = DirectCast(args.ExceptionObject, Exception)
      Console.WriteLine("MyHandler caught : " + e.Message)
      Console.WriteLine("Runtime terminating: {0}", args.IsTerminating)
   End Sub
End Module
' The example displays the following output:
'       Catch clause caught : 1
'       
'       MyHandler caught : 2
'       Runtime terminating: True
'       
'       Unhandled Exception: System.Exception: 2
'          at Example.Main()

注釈

このイベントは、キャッチされていない例外の通知を提供します。 これにより、システムの既定のハンドラーがユーザーに例外を報告し、アプリケーションを終了する前に、アプリケーションで例外に関する情報をログに記録できます。 アプリケーションの状態に関する十分な情報が利用可能な場合は、後で回復するためにプログラム データを保存するなど、他のアクションが実行される可能性があります。 例外が処理されないとプログラム データが破損する可能性があるため、注意が必要です。

注意

.NET Framework バージョン 1.0 および 1.1 では、アプリケーションの終了とデバッグのオプションは、このイベントが発生する前に、後ではなくユーザーに報告されます。

このイベントは、任意のアプリケーション ドメインで処理できます。 ただし、例外が発生したアプリケーション ドメインでイベントが発生するとは限りません。 例外は、該当する例外ハンドラーが見つからずにスレッドのスタック全体が巻き戻された場合にのみハンドルされないので、イベントを発生できる最初の場所は、スレッドが発生したアプリケーション ドメインにあります。

注意

.NET Framework バージョン 1.0 および 1.1 では、このイベントは、アプリケーションの起動時にシステムによって作成される既定のアプリケーション ドメインに対してのみ発生します。 アプリケーションが追加のアプリケーション ドメインを作成する場合、それらのアプリケーション ドメインでこのイベントのデリゲートを指定しても効果はありません。

イベントが既定の UnhandledException アプリケーション ドメインで処理される場合、スレッドが開始されたアプリケーション ドメインに関係なく、スレッド内のハンドルされない例外に対してイベントが発生します。 イベント ハンドラー UnhandledExceptionを持つアプリケーション ドメインでスレッドが開始された場合、そのアプリケーション ドメインでイベントが発生します。 そのアプリケーション ドメインが既定のアプリケーション ドメインではなく、既定のアプリケーション ドメインにもイベント ハンドラーがある場合、イベントは両方のアプリケーション ドメインで発生します。

たとえば、スレッドがアプリケーション ドメイン "AD1" で開始され、アプリケーション ドメイン "AD2" のメソッドが呼び出され、そこからアプリケーション ドメイン "AD3" のメソッドが呼び出され、そこで例外がスローされるとします。 イベントを発生できる最初の UnhandledException アプリケーション ドメインは "AD1" です。 そのアプリケーション ドメインが既定のアプリケーション ドメインでない場合は、既定のアプリケーション ドメインでもイベントを発生させることができます。

注意

共通言語ランタイムは、イベントのイベント ハンドラーの実行中にスレッドの中止を UnhandledException 中断します。

イベント ハンドラーに適切なフラグを ReliabilityContractAttribute 持つ属性がある場合、イベント ハンドラーは制約付き実行領域として扱われます。

.NET Framework 4 以降では、このイベントは、イベント ハンドラーがセキュリティクリティカルで属性を持HandleProcessCorruptedStateExceptionsAttributeたない限り、スタック オーバーフローやアクセス違反などのプロセスの状態を破損する例外に対しては発生しません。

.NET Framework バージョン 1.0 および 1.1 では、メイン アプリケーション スレッド以外のスレッドで発生するハンドルされない例外がランタイムによってキャッチされるため、アプリケーションは終了しません。 これにより、アプリケーションが UnhandledException 終了することなくイベントが発生する可能性があります。 .NET Framework バージョン 2.0 以降では、このようなサイレント エラーの累積的な影響にはパフォーマンスの低下、破損したデータ、ロックアップが含まれていたため、子スレッドの未処理の例外に対するこのバックストップは削除されました。これらはすべてデバッグが困難でした。 ランタイムが終了しないケースの一覧など、詳細については、「 マネージド スレッドの例外」を参照してください。

このイベントのイベント ハンドラーを登録するには、必要なアクセス許可を持っているか、a SecurityException がスローされる必要があります。

イベントの処理の詳細については、「処理とイベントの発生」を参照してください。

ハンドルされない例外のその他のイベント

特定のアプリケーション モデルでは、 UnhandledException メイン アプリケーション スレッドでハンドルされない例外が発生した場合に、他のイベントによってイベントが割り込まれる可能性があります。

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

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

適用対象