AppDomain.UnhandledException Událost
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Nastane, když není zachycena výjimka.
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
Event Type
Implementuje
- Atributy
Příklady
Následující příklad ukazuje UnhandledException událost. Definuje obslužnou rutinu události, MyHandlerkterá se vyvolá při každém neošetřené výjimce vyvolá ve výchozí doméně aplikace. Potom vyvolá dvě výjimky. První je zpracován blokem try/catch . Druhá je neošetřená a vyvolá rutinu MyHandle před ukončením aplikace.
// 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()
Poznámky
Obslužné rutiny mohou být vyvolány vícekrát, pokud jsou výjimky vyvolány z různých vláken.
Událost UnhandledException poskytuje oznámení o nezachycených výjimkách. Umožňuje aplikaci protokolovat informace o výjimce předtím, než výchozí obslužná rutina systému oznámí výjimku uživateli a ukončí aplikaci. Pokud je k dispozici dostatek informací o stavu aplikace, mohou být provedeny další akce, například ukládání dat programu pro pozdější obnovení. Upozornění se doporučuje, protože data programu se můžou poškodit, když se nezpracují výjimky. Obslužná rutina poběží i nadále, dokud drží zámky, které byly drženy ve chvíli vyvolání výjimky, proto je třeba dbát na to, aby se zabránilo čekání na jiné prostředky, což by mohlo vést k vzájemnému zablokování.
Tuto událost lze zpracovat v jakékoli doméně aplikace. Událost však nemusí být nutně vyvolána v doméně aplikace, kde došlo k výjimce. Výjimka je neošetřená pouze v případě, že byl celý zásobník pro vlákno rozmotán bez nalezení příslušné obslužné rutiny výjimky, takže první místo, kde může být událost vyvolána, je v doméně aplikace, odkud vlákno pochází.
UnhandledException Pokud je událost zpracována ve výchozí doméně aplikace, je vyvolána u jakékoli neošetřené výjimky v jakémkoli vlákně bez ohledu na to, v jaké doméně aplikace vlákno začalo. Pokud vlákno začalo běžet v aplikační doméně, která má obslužnou rutinu událostí pro UnhandledException, událost je vyvolána v této aplikační doméně. Pokud tato doména aplikace není výchozí doménou aplikace a ve výchozí doméně aplikace je také obslužná rutina události, vyvolá se událost v obou doménách aplikace.
Předpokládejme například, že vlákno začíná v doméně aplikace AD1, volá metodu v doméně aplikace AD2 a odtud volá metodu v doméně aplikace AD3, kde vyvolá výjimku. První doménou aplikace, ve které může být událost UnhandledException vyvolána, je „AD1“. Pokud tato doména aplikace není výchozí doménou aplikace, může být událost vyvolána také ve výchozí doméně aplikace.
Note
Modul Common Language Runtime (CLR) pozastaví přerušení vláken, zatímco se spouští obslužná rutina události UnhandledException.
Pokud obslužná rutina události má ReliabilityContractAttribute atribut s příslušnými příznaky, obslužná rutina události se považuje za omezenou oblast provádění.
Tato událost není vyvolána kvůli výjimkám, které poškodily stav procesu, jako jsou přetečení zásobníku nebo porušení přístupu, pokud obslužná rutina události není kritická pro zabezpečení a nemá HandleProcessCorruptedStateExceptionsAttribute atribut.
Chcete-li zaregistrovat obslužnou rutinu pro událost, musíte mít požadovaná oprávnění, jinak je vyvolán SecurityException.
Další informace o zpracování událostí naleznete v tématu Zpracování a vyvolávání událostí.
Další události týkající se neošetřených výjimek
V některých případech aplikačních modelů může být událost UnhandledException předstižena jinými událostmi, pokud dojde k neošetřené výjimce v hlavním vlákně aplikace.
V aplikacích, které používají model model Windows Forms, neošetřené výjimky v hlavním vlákně aplikace způsobí Application.ThreadException vyvolání události. Pokud se tato událost zpracuje, výchozí chování spočívá v tom, že neošetřená výjimka aplikaci neukončí, i když aplikace zůstane v neznámém stavu. V takovém případě se událost UnhandledException nevyvolá. Toto chování lze změnit pomocí konfiguračního souboru aplikace nebo pomocí Application.SetUnhandledExceptionMode metody změnit režim na UnhandledExceptionMode.ThrowException před ThreadException připojení obslužné rutiny události. To platí jenom pro hlavní vlákno aplikace. Událost UnhandledException je vyvolána pro neošetřené výjimky vyvolané v jiných vláknech.
Aplikační architektura jazyka Visual Basic poskytuje další událost pro neošetřené výjimky v hlavním vlákně aplikace – WindowsFormsApplicationBase.UnhandledException událost. Tato událost má objekt argumentů události se stejným názvem jako objekt argumentů události používaný AppDomain.UnhandledExceptionobjektem , ale s různými vlastnostmi. Konkrétně tento objekt argumentů události má ExitApplication vlastnost, která umožňuje aplikaci pokračovat ve spuštění, ignorování neošetřené výjimky (a ponechání aplikace v neznámém stavu). V takovém případě se událost AppDomain.UnhandledException nevyvolá.