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 ,每當預設應用程式域中擲回未處理的例外狀況時,就會叫用這個事件處理常式。 然後會擲回兩個例外狀況。 第一個是由 try/catch 區塊處理。 第二個未處理,並在應用程式終止之前叫 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」。 如果該應用程式域不是預設的應用程式域,事件也可以在預設應用程式域中引發。

注意

Common Language Runtime 會在事件的事件處理常式 UnhandledException 執行時暫停執行緒中止。

如果事件處理常式具有 ReliabilityContractAttribute 具有適當旗標的屬性,事件處理常式就會被視為受限的執列區域。

從 .NET Framework 4 開始,除非事件處理常式為安全性關鍵且具有 HandleProcessCorruptedStateExceptionsAttribute 屬性,否則不會針對損毀進程狀態的例外狀況引發此事件,例如堆疊溢位或存取違規。

在 .NET Framework 1.0 和 1.1 版中,執行時間會攔截主要應用程式執行緒以外的執行緒中發生的未處理例外狀況,因此不會造成應用程式終止。 因此,事件可以在 UnhandledException 不終止應用程式的情況下引發。 從 .NET Framework 2.0 版開始,已移除子執行緒中未處理的例外狀況,因為這類無訊息失敗的累積效果包括效能降低、損毀的資料和鎖定,這全部都難以偵錯。 如需詳細資訊,包括執行時間未終止的案例清單,請參閱 Managed 執行緒中的例外狀況

若要註冊此事件的事件處理常式,您必須具有必要的許可權,否則 SecurityException 會擲回 。

如需處理事件的詳細資訊,請參閱 處理和引發事件

未處理的例外狀況的其他事件

對於某些應用程式模型,如果主要應用程式執行緒中發生未處理的例外狀況, UnhandledException 事件可能會優先于其他事件。

在使用Windows Forms的應用程式中,主要應用程式執行緒中的未處理例外狀況會導致 Application.ThreadException 引發 事件。 如果處理此事件,預設行為是未處理的例外狀況不會終止應用程式,雖然應用程式處於未知狀態。 在此情況下, UnhandledException 不會引發 事件。 您可以使用應用程式組態檔來變更此行為,或使用 Application.SetUnhandledExceptionMode 方法將模式變更為 UnhandledExceptionMode.ThrowExceptionThreadException ,再連結事件處理常式。 這只適用于主要應用程式執行緒。 針對在其他執行緒中擲回的未處理例外狀況,會 UnhandledException 引發 事件。

從 visual Studio 2005 Microsoft開始,Visual Basic 應用程式架構會針對主要應用程式執行緒中未處理的例外狀況提供另一個事件。 WindowsFormsApplicationBase.UnhandledException請參閱 事件。 這個事件具有事件引數物件,其名稱與 所使用的 AppDomain.UnhandledException 事件引數物件相同,但具有不同的屬性。 特別是,這個事件引數物件具有 ExitApplication 屬性,可讓應用程式繼續執行,忽略未處理的例外狀況 (,並將應用程式保留在未知的狀態) 。 在此情況下, AppDomain.UnhandledException 不會引發 事件。

適用於