AppDomain.UnhandledException Zdarzenie
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Występuje, gdy wyjątek nie jest przechwycony.
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
Typ zdarzenia
Implementuje
- Atrybuty
Przykłady
W poniższym przykładzie pokazano UnhandledException zdarzenie. Definiuje procedurę obsługi zdarzeń , która jest wywoływana za każdym razem, MyHandlergdy w domyślnej domenie aplikacji jest zgłaszany nieobsługiwany wyjątek. Następnie zgłasza dwa wyjątki. Pierwszy jest obsługiwany przez blok try/catch . Drugi jest nieobsługiwany i wywołuje procedurę MyHandle przed zakończeniem działania aplikacji.
// 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()
Uwagi
Programy obsługi mogą być wywoływane wiele razy, jeśli wyjątki są zgłaszane z różnych wątków.
Zdarzenie UnhandledException zawiera powiadomienie o nieuchwyconych wyjątkach. Umożliwia aplikacji rejestrowanie informacji o wyjątku przed zgłoszeniem wyjątku użytkownikowi przez domyślny program obsługi systemu, który kończy działanie aplikacji. Jeśli jest dostępna wystarczająca ilość informacji o stanie aplikacji, mogą zostać podjęte inne akcje , takie jak zapisywanie danych programu na potrzeby późniejszego odzyskiwania. Zaleca się zachowanie ostrożności, ponieważ dane programu mogą stać się uszkodzone, gdy wyjątki nie są obsługiwane. Program obsługi będzie również uruchamiany podczas przechowywania blokad przechowywanych w momencie zgłoszenia wyjątku, dlatego należy zachować ostrożność, aby uniknąć oczekiwania na inne zasoby, które mogłyby spowodować zakleszczenia.
To zdarzenie można obsłużyć w dowolnej domenie aplikacji. Jednak zdarzenie nie musi być zgłaszane w domenie aplikacji, w której wystąpił wyjątek. Wyjątek jest nieobsługiwany tylko wtedy, gdy cały stos wątku został odwinięty bez znalezienia odpowiedniego obsługiwacza wyjątków, więc pierwsze miejsce, w którym można zgłosić zdarzenie, znajduje się w domenie aplikacji, z której pochodzi wątek.
UnhandledException Jeśli zdarzenie jest obsługiwane w domyślnej domenie aplikacji, jest zgłaszane tam dla nieobsługiwanego wyjątku w dowolnym wątku, niezależnie od domeny aplikacji, w której uruchomiono wątek. Jeśli wątek został uruchomiony w domenie aplikacji, która ma obsługę zdarzeń dla UnhandledException, zdarzenie zostanie zgłoszone w tej domenie aplikacji. Jeśli ta domena aplikacji nie jest domyślną domeną aplikacji i istnieje również program obsługi zdarzeń w domyślnej domenie aplikacji, zdarzenie jest zgłaszane w obu domenach aplikacji.
Załóżmy na przykład, że wątek rozpoczyna się w domenie aplikacji "AD1", wywołuje metodę w domenie aplikacji "AD2", a następnie wywołuje metodę w domenie aplikacji "AD3", gdzie zgłasza wyjątek. Pierwsza domena aplikacji, w której zdarzenie UnhandledException może być podniesione, to "AD1". Jeśli ta domena aplikacji nie jest domyślną domeną aplikacji, zdarzenie można również podnieść w domyślnej domenie aplikacji.
Note
Środowisko uruchomieniowe języka wspólnego zawiesza przerywanie wątków, gdy programy obsługi zdarzeń dla zdarzenia UnhandledException są wykonywane.
Jeśli program obsługi zdarzeń ma ReliabilityContractAttribute atrybut z odpowiednimi flagami, procedura obsługi zdarzeń jest traktowana jako ograniczony region wykonywania.
To zdarzenie nie jest zgłaszane w przypadku wyjątków, które uszkodziły stan procesu, takie jak przepełnienia stosu lub naruszenia dostępu, chyba że program obsługi zdarzeń jest krytyczny dla zabezpieczeń i ma HandleProcessCorruptedStateExceptionsAttribute atrybut .
Aby zarejestrować program obsługi zdarzeń dla tego zdarzenia, musisz mieć wymagane uprawnienia, w przeciwnym razie zgłaszany jest SecurityException.
Aby uzyskać więcej informacji na temat obsługi zdarzeń, zobacz Obsługa i wywoływanie zdarzeń.
Inne zdarzenia dla nieobsługiwanych wyjątków
W przypadku niektórych modeli aplikacji zdarzenie może zostać wywłaszczone przez inne zdarzenia, UnhandledException jeśli nieobsługiwany wyjątek występuje w głównym wątku aplikacji.
W aplikacjach korzystających z formularzy Systemu Windows nieobsługiwane wyjątki w głównym wątku aplikacji powodują Application.ThreadException zgłoszenie zdarzenia. Jeśli to zdarzenie jest obsługiwane, domyślne zachowanie polega na tym, że nieobsługiwany wyjątek nie kończy aplikacji, chociaż aplikacja pozostaje w nieznanym stanie. W takim przypadku UnhandledException zdarzenie nie jest zgłaszane. To zachowanie można zmienić przy użyciu pliku konfiguracji aplikacji lub za pomocą Application.SetUnhandledExceptionMode metody , aby zmienić tryb na przed UnhandledExceptionMode.ThrowException podłączeniem ThreadException programu obsługi zdarzeń. Dotyczy to tylko głównego wątku aplikacji. Zdarzenie UnhandledException jest zgłaszane dla nieobsługiwanych wyjątków zgłaszanych w innych wątkach.
Struktura aplikacji języka Visual Basic udostępnia kolejne zdarzenie dla nieobsługiwanych wyjątków w głównym wątku aplikacji — zdarzenie WindowsFormsApplicationBase.UnhandledException. To zdarzenie ma obiekt argumentów zdarzeń o tej samej nazwie co obiekt argumentów zdarzeń używany przez AppDomain.UnhandledException, ale z różnymi właściwościami. W szczególności ten obiekt argumentów zdarzeń ma ExitApplication właściwość, która umożliwia aplikacji kontynuowanie działania, ignorując nieobsługiwany wyjątek (i pozostawiając aplikację w nieznanym stanie). W takim przypadku AppDomain.UnhandledException zdarzenie nie jest zgłaszane.