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 

イベントの種類

実装

属性

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 以降では、このようなサイレント エラーの累積的な影響にはパフォーマンスの低下、破損したデータ、ロックアップが含まれていたため、子スレッドの未処理の例外に対するこのバックストップは削除されました。これらはすべてデバッグが困難でした。 ランタイムが終了しないケースの一覧など、詳細については、「 Managed Threads の例外」を参照してください。

このイベントのイベント ハンドラーを登録するには、必要なアクセス許可が必要です。または SecurityException がスローされます。

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

未処理例外のその他のイベント

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

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

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

適用対象