AppDomain.UnhandledException Ereignis
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Tritt auf, wenn eine Ausnahme nicht abgefangen wird.
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
Ereignistyp
Implementiert
- Attribute
Beispiele
Das folgende Beispiel veranschaulicht das UnhandledException Ereignis. Er definiert einen Ereignishandler, der aufgerufen wird, MyHandlerwenn eine unbehandelte Ausnahme in der Standardanwendungsdomäne ausgelöst wird. Anschließend werden zwei Ausnahmen ausgelöst. Der erste wird von einem Try/Catch-Block behandelt. Die zweite ist unbehandelt und ruft die MyHandle Routine auf, bevor die Anwendung beendet wird.
// 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()
Hinweise
Handler können mehrmals aufgerufen werden, wenn Ausnahmen aus verschiedenen Threads ausgelöst werden.
Das UnhandledException Ereignis bietet eine Benachrichtigung über nicht abgefangene Ausnahmen. Die Anwendung ermöglicht es der Anwendung, Informationen über die Ausnahme zu protokollieren, bevor der Systemstandardhandler die Ausnahme an den Benutzer meldet und die Anwendung beendet. Wenn ausreichende Informationen über den Anwendungsstatus verfügbar sind, können weitere Maßnahmen ergriffen werden , z. B. das Speichern von Programmdaten für eine spätere Wiederherstellung. Vorsicht wird empfohlen, da Programmdaten beschädigt werden können, wenn Ausnahmen nicht behandelt werden. Der Handler wird auch ausgeführt, während Sperren gehalten werden, wenn die Ausnahme ausgelöst wurde. Daher sollten Sie darauf achten, nicht auf andere Ressourcen zu warten, die Deadlocks hervorrufen könnten.
Dieses Ereignis kann in einer beliebigen Anwendungsdomäne behandelt werden. Das Ereignis wird jedoch nicht unbedingt in der Anwendungsdomäne ausgelöst, in der die Ausnahme aufgetreten ist. Eine Ausnahme ist nur dann unbehandelt, wenn der gesamte Stapel für den Thread entwoben wurde, ohne einen anwendbaren Ausnahmehandler zu finden. Daher befindet sich der erste Ort, an dem das Ereignis ausgelöst werden kann, in der Anwendungsdomäne, in der der Thread stammt.
Wenn das UnhandledException Ereignis in der Standardanwendungsdomäne behandelt wird, wird es für alle unbehandelten Ausnahmen in einem Thread ausgelöst, unabhängig davon, in welcher Anwendungsdomäne der Thread gestartet wurde. Wenn der Thread in einer Anwendungsdomäne gestartet wurde, für die ein Ereignishandler vorhanden UnhandledExceptionist, wird das Ereignis in dieser Anwendungsdomäne ausgelöst. Wenn diese Anwendungsdomäne nicht die Standardanwendungsdomäne ist und es auch einen Ereignishandler in der Standardanwendungsdomäne gibt, wird das Ereignis in beiden Anwendungsdomänen ausgelöst.
Angenommen, ein Thread beginnt in der Anwendungsdomäne "AD1", ruft eine Methode in der Anwendungsdomäne "AD2" auf, und von dort wird eine Methode in der Anwendungsdomäne "AD3" aufgerufen, wobei eine Ausnahme ausgelöst wird. Die erste Anwendungsdomäne, in der das UnhandledException Ereignis ausgelöst werden kann, ist "AD1". Wenn diese Anwendungsdomäne nicht die Standardanwendungsdomäne ist, kann das Ereignis auch in der Standardanwendungsdomäne ausgelöst werden.
Note
Die Common Language Runtime hält Threadabbrüche an, während Ereignishandler für das UnhandledException Ereignis ausgeführt werden.
Wenn der Ereignishandler über ein ReliabilityContractAttribute Attribut mit den entsprechenden Flags verfügt, wird der Ereignishandler als eingeschränkter Ausführungsbereich behandelt.
Dieses Ereignis wird nicht für Ausnahmen ausgelöst, die den Status des Prozesses beschädigen, z. B. Stapelüberläufe oder Zugriffsverletzungen, es sei denn, der Ereignishandler ist sicherheitskritisch und hat das HandleProcessCorruptedStateExceptionsAttribute Attribut.
Um einen Ereignishandler für dieses Ereignis zu registrieren, müssen Sie über die erforderlichen Berechtigungen verfügen, da sonst ein SecurityException ausgelöst wird.
Weitere Informationen zur Behandlung von Ereignissen finden Sie unter behandeln und Auslösen von Ereignissen.
Andere Ereignisse für unbehandelte Ausnahmen
Bei bestimmten Anwendungsmodellen kann das UnhandledException Ereignis von anderen Ereignissen unterbrochen werden, wenn die unbehandelte Ausnahme im Hauptanwendungsthread auftritt.
In Anwendungen, die Windows Forms verwenden, führen unbehandelte Ausnahmen im Hauptanwendungsthread dazu, dass das Application.ThreadException Ereignis ausgelöst wird. Wenn dieses Ereignis behandelt wird, ist das Standardverhalten, dass die unbehandelte Ausnahme die Anwendung nicht beendet, obwohl die Anwendung in einem unbekannten Zustand verbleibt. In diesem Fall wird das UnhandledException Ereignis nicht ausgelöst. Dieses Verhalten kann mithilfe der Anwendungskonfigurationsdatei oder mithilfe der Application.SetUnhandledExceptionMode Methode geändert werden, um den Modus UnhandledExceptionMode.ThrowException zu ändern, bevor der ThreadException Ereignishandler eingebunden wird. Dies gilt nur für den Hauptanwendungsthread. Das UnhandledException Ereignis wird für unbehandelte Ausnahmen ausgelöst, die in anderen Threads ausgelöst werden.
Das Visual Basic-Anwendungsframework stellt ein weiteres Ereignis für unbehandelte Ausnahmen im Hauptanwendungsthread bereit – das WindowsFormsApplicationBase.UnhandledException Ereignis. Dieses Ereignis verfügt über ein Ereignisargumentobjekt mit demselben Namen wie das von AppDomain.UnhandledException, aber mit unterschiedlichen Eigenschaften verwendete Ereignisargumentobjekt. Insbesondere verfügt dieses Ereignisargumentobjekt über eine ExitApplication Eigenschaft, die es der Anwendung ermöglicht, die Ausführung fortzusetzen, wobei die unbehandelte Ausnahme ignoriert wird (und die Anwendung in einem unbekannten Zustand bleibt). In diesem Fall wird das AppDomain.UnhandledException Ereignis nicht ausgelöst.