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который вызывается всякий раз, когда необработанное исключение создается в домене приложения по умолчанию. Затем создается два исключения. Первый обрабатывается блоком 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()

Комментарии

Обработчики могут вызываться несколько раз, если исключения создаются из разных потоков.

Это UnhandledException событие предоставляет уведомление об неухваченных исключениях. Он позволяет приложению регистрировать сведения об исключении, прежде чем системный обработчик по умолчанию сообщает об исключении пользователю и завершает работу приложения. Если доступна достаточная информация о состоянии приложения, можно выполнить другие действия, например сохранение данных программы для последующего восстановления. Рекомендуется соблюдать осторожность, так как данные программы могут быть повреждены, если исключения не обрабатываются. Обработчик также будет работать, удерживая блокировки, существовавшие при возникновении исключения, поэтому нужно проявить осторожность, чтобы избегать ожидания освобождения других ресурсов, которые могут привести к взаимоблокировкам.

Это событие можно обрабатывать в любом домене приложения. Однако событие не обязательно вызывается в домене приложения, где произошло исключение. Исключение является необработанным только в том случае, если весь стек для потока был размотан без поиска применимого обработчика исключений, поэтому первое место, где может быть поднято событие, находится в домене приложения, в котором поток был инициирован.

UnhandledException Если событие обрабатывается в домене приложения по умолчанию, оно вызывается для любого необработанного исключения в любом потоке независимо от того, в каком домене приложения запущен поток. Если поток запускается в домене приложения, который имеет обработчик событий для UnhandledException, то событие вызывается в этом домене приложения. Если этот домен приложения не является доменом приложения по умолчанию, а в домене приложения по умолчанию есть обработчик событий, событие вызывается в обоих доменах приложения.

Например, предположим, что поток начинается в домене приложения "AD1", вызывает метод в домене приложения "AD2", а оттуда вызывает метод в домене приложения "AD3", где он создает исключение. Первый домен приложения, в котором можно вызвать событие, — это "AD1". Если этот домен приложения не является доменом приложения по умолчанию, событие также может быть поднято в домене приложения по умолчанию.

Замечание

Среда CLR приостанавливает прерывания потоков во время выполнения обработчиков событий для UnhandledException события.

Если обработчик событий имеет ReliabilityContractAttribute атрибут с соответствующими флагами, обработчик событий обрабатывается как ограниченный регион выполнения.

Это событие не вызывается для исключений, которые повреждают состояние процесса, например переполнения стека или нарушения доступа, если обработчик событий не является критически важным для безопасности и имеет HandleProcessCorruptedStateExceptionsAttribute атрибут.

Чтобы зарегистрировать обработчик для этого события, необходимо иметь соответствующие разрешения, в противном случае возникает SecurityException.

Дополнительные сведения об обработке событий см. в разделе "Обработка и создание событий".

Другие события для необработанных исключений

Для некоторых моделей приложений событие UnhandledException может быть перехвачено другими событиями, если необработанное исключение возникает в основном потоке приложения.

В приложениях, использующих Windows Forms, необработанные исключения в основном потоке приложения вызывают событие Application.ThreadException. Если это событие обрабатывается, поведение по умолчанию заключается в том, что необработанное исключение не завершает работу приложения, хотя приложение остается в неизвестном состоянии. В этом случае UnhandledException событие не вызывается. Это поведение можно изменить с помощью файла конфигурации приложения или можно воспользоваться методом Application.SetUnhandledExceptionMode, чтобы изменить режим UnhandledExceptionMode.ThrowException до того, как будет подключен обработчик событий ThreadException. Это относится только к основному потоку приложения. Событие UnhandledException генерируется для необработанных исключений, возникающих в других потоках.

Платформа приложений Visual Basic предоставляет ещё одно событие для необработанных исключений в основном потоке приложения — событие WindowsFormsApplicationBase.UnhandledException. Это событие имеет объект аргументов событий с тем же именем, что и объект аргументов событий, используемый AppDomain.UnhandledExceptionобъектом, но с различными свойствами. В частности, этот объект аргументов событий имеет ExitApplication свойство, которое позволяет приложению продолжать работу, игнорируя необработанное исключение (и оставляя приложение в неизвестном состоянии). В этом случае AppDomain.UnhandledException событие не вызывается.

Применяется к