AppDomain.UnhandledException Événement
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Se produit lorsqu’une exception n’est pas interceptée.
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
Type d’événement
Implémente
- Attributs
Exemples
L’exemple suivant illustre l’événement UnhandledException . Il définit un gestionnaire d’événements, MyHandlerqui est appelé chaque fois qu’une exception non gérée est levée dans le domaine d’application par défaut. Il lève ensuite deux exceptions. Le premier est géré par un bloc try/catch . La seconde est non gérée et appelle la routine avant la MyHandle fin de l’application.
// 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()
Remarques
Les gestionnaires peuvent être appelés plusieurs fois si des exceptions sont levées à partir de threads différents.
L’événement UnhandledException fournit une notification des exceptions non capturées. Elle permet à l’application de consigner des informations sur l’exception avant que le gestionnaire système par défaut signale l’exception à l’utilisateur et termine l’application. Si des informations suffisantes sur l’état de l’application sont disponibles, d’autres actions peuvent être effectuées, telles que l’enregistrement des données du programme pour une récupération ultérieure. La prudence est recommandée, car les données du programme peuvent être endommagées lorsque les exceptions ne sont pas gérées. Le gestionnaire continuera également à s'exécuter tout en conservant les verrous détenus au moment où l'exception a été levée. Il convient donc de veiller à ne pas attendre d'autres ressources qui pourraient entraîner des interblocages.
Cet événement peut être géré dans n’importe quel domaine d’application. Toutefois, l’événement n’est pas nécessairement déclenché dans le domaine d’application où l’exception s’est produite. Une exception n'est pas gérée uniquement si la pile entière du thread a été déroulée sans trouver de gestionnaire d'exception applicable. Le premier emplacement où l'événement peut être levé est donc le domaine d'application où le thread a été créé.
Si l’événement UnhandledException est géré dans le domaine d’application par défaut, il est déclenché pour toute exception non gérée dans n’importe quel thread, quel que soit le domaine d’application dans lequel le thread a démarré. Si le thread a démarré dans un domaine d’application pour lequel un gestionnaire UnhandledExceptiond’événements est associé, l’événement est déclenché dans ce domaine d’application. Si ce domaine d’application n’est pas le domaine d’application par défaut et qu’il existe également un gestionnaire d’événements dans le domaine d’application par défaut, l’événement est déclenché dans les deux domaines d’application.
Par exemple, supposons qu’un thread démarre dans le domaine d’application « AD1 », appelle une méthode dans le domaine d’application « AD2 » et, à partir de là, appelle une méthode dans le domaine d’application « AD3 », où elle lève une exception. Le premier domaine d’application dans lequel l’événement UnhandledException peut être déclenché est « AD1 ». Si ce domaine d’application n’est pas le domaine d’application par défaut, l’événement peut également être déclenché dans le domaine d’application par défaut.
Note
Le Common Language Runtime suspend les interruptions de thread pendant l'exécution des gestionnaires d'événements pour l'événement UnhandledException.
Si le gestionnaire d’événements a un ReliabilityContractAttribute attribut avec les indicateurs appropriés, le gestionnaire d’événements est traité comme une région d’exécution contrainte.
Cet événement n’est pas déclenché pour les exceptions qui endommagent l’état du processus, tels que les dépassements de capacité de pile ou les violations d’accès, sauf si le gestionnaire d’événements est critique pour la sécurité et a l’attribut HandleProcessCorruptedStateExceptionsAttribute .
Pour enregistrer un gestionnaire d'événements pour cet événement, vous devez disposer des permissions requises, sinon une exception SecurityException est levée.
Pour plus d'informations sur la gestion des événements, voir gestion et déclenchement d’événements.
Autres événements pour les exceptions non gérées
Pour certains modèles d’application, l’événement UnhandledException peut être préempté par d’autres événements si l’exception non gérée se produit dans le thread d’application principal.
Dans les applications qui utilisent Windows Forms, les exceptions non gérées dans le thread d’application principal entraînent le déclenchement de l’événement Application.ThreadException. Si cet événement est géré, le comportement par défaut est que l’exception non gérée n’arrête pas l’application, bien que l’application soit laissée dans un état inconnu. Dans ce cas, l’événement UnhandledException n’est pas déclenché. Ce comportement peut être modifié à l’aide du fichier de configuration de l’application ou à l’aide de la Application.SetUnhandledExceptionMode méthode pour modifier le mode UnhandledExceptionMode.ThrowException avant que le ThreadException gestionnaire d’événements soit branché. Cela s’applique uniquement au thread d’application principal. L’événement UnhandledException est déclenché pour les exceptions non gérées levées dans d’autres threads.
L’infrastructure d’application Visual Basic fournit un autre événement pour les exceptions non gérées dans le thread d’application principal, l’événement WindowsFormsApplicationBase.UnhandledException . Cet événement a un objet d’arguments d’événement portant le même nom que l’objet d’arguments d’événement utilisé par AppDomain.UnhandledException, mais avec des propriétés différentes. En particulier, cet objet arguments d’événement a une ExitApplication propriété qui permet à l’application de continuer à s’exécuter, en ignorant l’exception non gérée (et en laissant l’application dans un état inconnu). Dans ce cas, l’événement AppDomain.UnhandledException n’est pas déclenché.