Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka:
Tento článek je specifický pro rozhraní .NET Framework. Nevztahuje se na novější implementace .NET, včetně .NET 6 a novějších verzí.
Událost FirstChanceException třídy AppDomain umožňuje obdržet oznámení, že došlo k výjimce dříve, než modul CLR (Common Language Runtime) začal hledat obslužné rutiny výjimek.
Událost se vyvolá na úrovni domény aplikace. Vlákno provádění může procházet několika aplikačními doménami, takže výjimka, která je neošetřená v jedné aplikační doméně, by mohla být zpracována v jiné aplikační doméně. K oznámení dochází v každé doméně aplikace, která přidala obslužnou rutinu události, dokud doména aplikace nezpracuje výjimku.
Postupy a příklady v tomto článku ukazují, jak přijímat oznámení o výjimce první šance v jednoduchém programu, který má jednu doménu aplikace a v doméně aplikace, kterou vytvoříte.
Složitější příklad, který zahrnuje několik domén aplikace, najdete v příkladu události FirstChanceException.
Příjem oznámení o výjimce First-Chance ve výchozí doméně aplikace
V následujícím postupu se vstupní bod aplikace, metoda Main()
, spouští ve výchozí doméně aplikace.
Pro předvedení oznámení o výjimce první šance ve výchozí doméně aplikace
Definujte obslužnou rutinu události pro FirstChanceException událost pomocí funkce lambda a připojte ji k události. V tomto příkladu obslužná rutina události vytiskne název domény aplikace, kde byla událost zpracována, a vlastnost Message výjimky.
using System; using System.Runtime.ExceptionServices; class Example { static void Main() { AppDomain.CurrentDomain.FirstChanceException += (object source, FirstChanceExceptionEventArgs e) => { Console.WriteLine($"FirstChanceException event raised in {AppDomain.CurrentDomain.FriendlyName}: {e.Exception.Message}"); };
Imports System.Runtime.ExceptionServices Class Example Shared Sub Main() AddHandler AppDomain.CurrentDomain.FirstChanceException, Sub(source As Object, e As FirstChanceExceptionEventArgs) Console.WriteLine("FirstChanceException event raised in {0}: {1}", AppDomain.CurrentDomain.FriendlyName, e.Exception.Message) End Sub
Vyvolá výjimku a zachytí ji. Než modul runtime vyhledá obslužnou rutinu výjimky, vyvolá se událost FirstChanceException a zobrazí zprávu. Za touto zprávou následuje zpráva zobrazená obslužnou rutinou výjimky.
try { throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName); } catch (ArgumentException ex) { Console.WriteLine($"ArgumentException caught in {AppDomain.CurrentDomain.FriendlyName}: {ex.Message}"); }
Try Throw New ArgumentException("Thrown in " & AppDomain.CurrentDomain.FriendlyName) Catch ex As ArgumentException Console.WriteLine("ArgumentException caught in {0}: {1}", AppDomain.CurrentDomain.FriendlyName, ex.Message) End Try
Vyvolejte výjimku, ale nezachyťte ji. Než modul runtime začne vyhledávat obslužnou rutinu pro výjimky, je vyvolána událost FirstChanceException a zobrazí se zpráva. Neexistuje žádná obslužná rutina výjimky, takže aplikace je ukončena.
throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName); } }
Throw New ArgumentException("Thrown in " & AppDomain.CurrentDomain.FriendlyName) End Sub End Class
Kód zobrazený v prvních třech krocích tohoto postupu tvoří úplnou konzolovou aplikaci. Výstup aplikace se liší v závislosti na názvu souboru .exe, protože název výchozí domény aplikace se skládá z názvu a přípony souboru .exe. Ukázkový výstup najdete v následujícím příkladu.
/* This example produces output similar to the following: FirstChanceException event raised in Example.exe: Thrown in Example.exe ArgumentException caught in Example.exe: Thrown in Example.exe FirstChanceException event raised in Example.exe: Thrown in Example.exe Unhandled Exception: System.ArgumentException: Thrown in Example.exe at Example.Main() */
' This example produces output similar to the following: ' 'FirstChanceException event raised in Example.exe: Thrown in Example.exe 'ArgumentException caught in Example.exe: Thrown in Example.exe 'FirstChanceException event raised in Example.exe: Thrown in Example.exe ' 'Unhandled Exception: System.ArgumentException: Thrown in Example.exe ' at Example.Main()
Příjem oznámení o výjimce First-Chance v jiné doméně aplikace
Pokud váš program obsahuje více než jednu doménu aplikace, můžete zvolit, které domény aplikace přijímají oznámení.
Chcete-li přijímat oznámení o výjimkách první šance v aplikační doméně, kterou vytvoříte
Definujte obslužnou proceduru pro událost FirstChanceException. Tento příklad používá metodu
static
(metodaShared
v jazyce Visual Basic), která vytiskne název domény aplikace, kde byla událost zpracována, a vlastnost Message výjimky.static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e) { Console.WriteLine($"FirstChanceException event raised in {AppDomain.CurrentDomain.FriendlyName}: {e.Exception.Message}"); }
Shared Sub FirstChanceHandler(ByVal source As Object, ByVal e As FirstChanceExceptionEventArgs) Console.WriteLine("FirstChanceException event raised in {0}: {1}", AppDomain.CurrentDomain.FriendlyName, e.Exception.Message) End Sub
Vytvořte doménu aplikace a přidejte obslužnou rutinu události do FirstChanceException události pro danou doménu aplikace. V tomto příkladu má doména aplikace název
AD1
.AppDomain ad = AppDomain.CreateDomain("AD1"); ad.FirstChanceException += FirstChanceHandler;
Dim ad As AppDomain = AppDomain.CreateDomain("AD1") AddHandler ad.FirstChanceException, AddressOf FirstChanceHandler
Tuto událost můžete zpracovat ve výchozí doméně aplikace stejným způsobem. Pomocí vlastnosti
static
(Shared
v jazyce Visual Basic) AppDomain.CurrentDomain vMain()
získejte odkaz na výchozí doménu aplikace.
Předvedení oznámení o výjimce první šance v doméně aplikace
Vytvořte objekt
Worker
v doméně aplikace, kterou jste vytvořili v předchozím postupu. TřídaWorker
musí být veřejná a musí být odvozena od MarshalByRefObject, jak je znázorněno v úplném příkladu na konci tohoto článku.Worker w = (Worker) ad.CreateInstanceAndUnwrap( typeof(Worker).Assembly.FullName, "Worker");
Dim w As Worker = CType(ad.CreateInstanceAndUnwrap( GetType(Worker).Assembly.FullName, "Worker"), Worker)
Zavolejte metodu objektu
Worker
, která vyvolá výjimku. V tomto příkladu se metodaThrower
volá dvakrát. Poprvé je argument metodytrue
, což způsobí, že metoda zachytí vlastní výjimku. Druhý argument jefalse
a metodaMain()
zachytí výjimku ve výchozí doméně aplikace.// The worker throws an exception and catches it. w.Thrower(true); try { // The worker throws an exception and doesn't catch it. w.Thrower(false); } catch (ArgumentException ex) { Console.WriteLine($"ArgumentException caught in {AppDomain.CurrentDomain.FriendlyName}: {ex.Message}"); }
' The worker throws an exception and catches it. w.Thrower(true) Try ' The worker throws an exception and doesn't catch it. w.Thrower(false) Catch ex As ArgumentException Console.WriteLine("ArgumentException caught in {0}: {1}", AppDomain.CurrentDomain.FriendlyName, ex.Message) End Try
Umístěte kód do
Thrower
metody, abyste mohli řídit, jestli metoda zpracovává vlastní výjimku.if (catchException) { try { throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName); } catch (ArgumentException ex) { Console.WriteLine($"ArgumentException caught in {AppDomain.CurrentDomain.FriendlyName}: {ex.Message}"); } } else { throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName); }
If catchException Try Throw New ArgumentException("Thrown in " & AppDomain.CurrentDomain.FriendlyName) Catch ex As ArgumentException Console.WriteLine("ArgumentException caught in {0}: {1}", AppDomain.CurrentDomain.FriendlyName, ex.Message) End Try Else Throw New ArgumentException("Thrown in " & AppDomain.CurrentDomain.FriendlyName) End If
Příklad
Následující příklad vytvoří doménu aplikace s názvem AD1
a přidá obslužnou rutinu události do FirstChanceException události domény aplikace. Příklad vytvoří instanci třídy Worker
v doméně aplikace a volá metodu s názvem Thrower
, která vyvolá ArgumentException. V závislosti na hodnotě argumentu metoda buď zachytí výjimku, nebo ji nezpracuje.
Pokaždé, když metoda Thrower
vyvolá výjimku ve AD1
, je událost FirstChanceException vyvolána v AD1
a obslužná rutina události zobrazí zprávu. Modul runtime pak vyhledá obslužnou rutinu výjimky. V prvním případě se obslužná rutina výjimky nachází v AD1
. V druhém případě je výjimka neošetřená v AD1
a místo toho je zachycena ve výchozí doméně aplikace.
Poznámka:
Název výchozí domény aplikace je stejný jako název spustitelného souboru.
Pokud přidáte obslužnou rutinu události FirstChanceException do výchozí domény aplikace, událost se vyvolá a zpracuje před tím, než výchozí doména aplikace zpracuje výjimku. Pokud to chcete vidět, přidejte na začátek Main()
kód jazyka C# AppDomain.CurrentDomain.FirstChanceException += FirstChanceException;
(v jazyce Visual Basic, AddHandler AppDomain.CurrentDomain.FirstChanceException, FirstChanceException
).
using System;
using System.Reflection;
using System.Runtime.ExceptionServices;
class Example
{
static void Main()
{
// To receive first chance notifications of exceptions in
// an application domain, handle the FirstChanceException
// event in that application domain.
AppDomain ad = AppDomain.CreateDomain("AD1");
ad.FirstChanceException += FirstChanceHandler;
// Create a worker object in the application domain.
Worker w = (Worker) ad.CreateInstanceAndUnwrap(
typeof(Worker).Assembly.FullName, "Worker");
// The worker throws an exception and catches it.
w.Thrower(true);
try
{
// The worker throws an exception and doesn't catch it.
w.Thrower(false);
}
catch (ArgumentException ex)
{
Console.WriteLine($"ArgumentException caught in {AppDomain.CurrentDomain.FriendlyName}: {ex.Message}");
}
}
static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e)
{
Console.WriteLine($"FirstChanceException event raised in {AppDomain.CurrentDomain.FriendlyName}: {e.Exception.Message}");
}
}
public class Worker : MarshalByRefObject
{
public void Thrower(bool catchException)
{
if (catchException)
{
try
{
throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName);
}
catch (ArgumentException ex)
{
Console.WriteLine($"ArgumentException caught in {AppDomain.CurrentDomain.FriendlyName}: {ex.Message}");
}
}
else
{
throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName);
}
}
}
/* This example produces output similar to the following:
FirstChanceException event raised in AD1: Thrown in AD1
ArgumentException caught in AD1: Thrown in AD1
FirstChanceException event raised in AD1: Thrown in AD1
ArgumentException caught in Example.exe: Thrown in AD1
*/
Imports System.Reflection
Imports System.Runtime.ExceptionServices
Class Example
Shared Sub Main()
' To receive first chance notifications of exceptions in
' an application domain, handle the FirstChanceException
' event in that application domain.
Dim ad As AppDomain = AppDomain.CreateDomain("AD1")
AddHandler ad.FirstChanceException, AddressOf FirstChanceHandler
' Create a worker object in the application domain.
Dim w As Worker = CType(ad.CreateInstanceAndUnwrap(
GetType(Worker).Assembly.FullName, "Worker"),
Worker)
' The worker throws an exception and catches it.
w.Thrower(true)
Try
' The worker throws an exception and doesn't catch it.
w.Thrower(false)
Catch ex As ArgumentException
Console.WriteLine("ArgumentException caught in {0}: {1}",
AppDomain.CurrentDomain.FriendlyName, ex.Message)
End Try
End Sub
Shared Sub FirstChanceHandler(ByVal source As Object,
ByVal e As FirstChanceExceptionEventArgs)
Console.WriteLine("FirstChanceException event raised in {0}: {1}",
AppDomain.CurrentDomain.FriendlyName, e.Exception.Message)
End Sub
End Class
Public Class Worker
Inherits MarshalByRefObject
Public Sub Thrower(ByVal catchException As Boolean)
If catchException
Try
Throw New ArgumentException("Thrown in " & AppDomain.CurrentDomain.FriendlyName)
Catch ex As ArgumentException
Console.WriteLine("ArgumentException caught in {0}: {1}",
AppDomain.CurrentDomain.FriendlyName, ex.Message)
End Try
Else
Throw New ArgumentException("Thrown in " & AppDomain.CurrentDomain.FriendlyName)
End If
End Sub
End Class
' This example produces output similar to the following:
'
'FirstChanceException event raised in AD1: Thrown in AD1
'ArgumentException caught in AD1: Thrown in AD1
'FirstChanceException event raised in AD1: Thrown in AD1
'ArgumentException caught in Example.exe: Thrown in AD1