Procedure: Uitzonderingsmeldingen voor eerste kans ontvangen
Notitie
Dit artikel is specifiek voor .NET Framework. Dit geldt niet voor nieuwere implementaties van .NET, waaronder .NET 6 en nieuwere versies.
Met FirstChanceException de gebeurtenis van de AppDomain klasse kunt u een melding ontvangen dat er een uitzondering is opgetreden, voordat de algemene taalruntime is begonnen met het zoeken naar uitzonderingshandlers.
De gebeurtenis wordt gegenereerd op het niveau van het toepassingsdomein. Een thread van uitvoering kan meerdere toepassingsdomeinen passeren, zodat een uitzondering die niet wordt verwerkt in het ene toepassingsdomein kan worden verwerkt in een ander toepassingsdomein. De melding vindt plaats in elk toepassingsdomein dat een handler voor de gebeurtenis heeft toegevoegd, totdat een toepassingsdomein de uitzondering afhandelt.
De procedures en voorbeelden in dit artikel laten zien hoe u uitzonderingsmeldingen voor de eerste kans ontvangt in een eenvoudig programma met één toepassingsdomein en in een toepassingsdomein dat u maakt.
Zie het voorbeeld voor de FirstChanceException gebeurtenis voor een complexer voorbeeld dat meerdere toepassingsdomeinen omvat.
Eerste kans uitzonderingsmeldingen ontvangen in het standaardtoepassingsdomein
In de volgende procedure wordt het toegangspunt voor de toepassing, de Main()
methode, uitgevoerd in het standaardtoepassingsdomein.
Uitzonderingsmeldingen voor de eerste kans demonstreren in het standaardtoepassingsdomein
Definieer een gebeurtenis-handler voor de FirstChanceException gebeurtenis met behulp van een lambda-functie en koppel deze aan de gebeurtenis. In dit voorbeeld drukt de gebeurtenis-handler de naam van het toepassingsdomein af waar de gebeurtenis is verwerkt en de eigenschap van Message de uitzondering.
using System; using System.Runtime.ExceptionServices; class Example { static void Main() { AppDomain.CurrentDomain.FirstChanceException += (object source, FirstChanceExceptionEventArgs e) => { Console.WriteLine("FirstChanceException event raised in {0}: {1}", 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
Gooi een uitzondering en pak het. Voordat de runtime de uitzonderingshandler vindt, wordt de FirstChanceException gebeurtenis gegenereerd en wordt een bericht weergegeven. Dit bericht wordt gevolgd door het bericht dat wordt weergegeven door de uitzonderingshandler.
try { throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName); } catch (ArgumentException ex) { Console.WriteLine("ArgumentException caught in {0}: {1}", 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
Gooi een uitzondering, maar pak het niet. Voordat de runtime naar een uitzonderingshandler zoekt, wordt de FirstChanceException gebeurtenis gegenereerd en wordt er een bericht weergegeven. Er is geen uitzonderingshandler, dus de toepassing wordt beëindigd.
throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName); } }
Throw New ArgumentException("Thrown in " & AppDomain.CurrentDomain.FriendlyName) End Sub End Class
De code die in de eerste drie stappen van deze procedure wordt weergegeven, vormt een volledige consoletoepassing. De uitvoer van de toepassing varieert, afhankelijk van de naam van het .exe-bestand, omdat de naam van het standaardtoepassingsdomein bestaat uit de naam en extensie van het .exe-bestand. Zie het volgende voor voorbeelduitvoer.
/* 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()
Uitzonderingsmeldingen voor eerste kans ontvangen in een ander toepassingsdomein
Als uw programma meer dan één toepassingsdomein bevat, kunt u kiezen welke toepassingsdomeinen meldingen ontvangen.
Uitzonderingsmeldingen voor de eerste kans ontvangen in een toepassingsdomein dat u maakt
Definieer een gebeurtenis-handler voor de FirstChanceException gebeurtenis. In dit voorbeeld wordt een
static
methode (Shared
methode in Visual Basic) gebruikt waarmee de naam van het toepassingsdomein wordt afgedrukt waarop de gebeurtenis is verwerkt en de eigenschap van Message de uitzondering.static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e) { Console.WriteLine("FirstChanceException event raised in {0}: {1}", 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
Maak een toepassingsdomein en voeg de gebeurtenis-handler toe aan de FirstChanceException gebeurtenis voor dat toepassingsdomein. In dit voorbeeld heeft het toepassingsdomein de naam
AD1
.AppDomain ad = AppDomain.CreateDomain("AD1"); ad.FirstChanceException += FirstChanceHandler;
Dim ad As AppDomain = AppDomain.CreateDomain("AD1") AddHandler ad.FirstChanceException, AddressOf FirstChanceHandler
U kunt deze gebeurtenis op dezelfde manier afhandelen in het standaardtoepassingsdomein. Gebruik de
static
eigenschapMain()
(Shared
in Visual Basic) AppDomain.CurrentDomain om een verwijzing naar het standaardtoepassingsdomein op te halen.
Uitzonderingsmeldingen voor de eerste kans demonstreren in het toepassingsdomein
Maak een
Worker
object in het toepassingsdomein dat u in de vorige procedure hebt gemaakt. DeWorker
klasse moet openbaar zijn en moet zijn afgeleid van MarshalByRefObject, zoals wordt weergegeven in het volledige voorbeeld aan het einde van dit artikel.Worker w = (Worker) ad.CreateInstanceAndUnwrap( typeof(Worker).Assembly.FullName, "Worker");
Dim w As Worker = CType(ad.CreateInstanceAndUnwrap( GetType(Worker).Assembly.FullName, "Worker"), Worker)
Roep een methode aan van het
Worker
object dat een uitzondering genereert. In dit voorbeeld wordt deThrower
methode twee keer aangeroepen. De eerste keer istrue
het methodeargument, wat ervoor zorgt dat de methode een eigen uitzondering ondervangt. De tweede keer isfalse
het argument en deMain()
methode wordt de uitzondering in het standaardtoepassingsdomein onderschept.// 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 {0}: {1}", 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
Plaats code in de
Thrower
methode om te bepalen of de methode een eigen uitzondering afhandelt.if (catchException) { try { throw new ArgumentException("Thrown in " + AppDomain.CurrentDomain.FriendlyName); } catch (ArgumentException ex) { Console.WriteLine("ArgumentException caught in {0}: {1}", 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
Opmerking
In het volgende voorbeeld wordt een toepassingsdomein gemaakt met de naam AD1
en wordt een gebeurtenishandler toegevoegd aan de gebeurtenis van FirstChanceException het toepassingsdomein. In het voorbeeld wordt een exemplaar van de Worker
klasse in het toepassingsdomein gemaakt en wordt een methode aangeroepen met de naam Thrower
die een ArgumentException. Afhankelijk van de waarde van het argument wordt de uitzondering onderschept of niet verwerkt.
Telkens wanneer de Thrower
methode een uitzondering AD1
genereert, wordt de FirstChanceException gebeurtenis gegenereerd in AD1
en geeft de gebeurtenis-handler een bericht weer. De runtime zoekt vervolgens naar een uitzonderingshandler. In het eerste geval wordt de uitzonderingshandler gevonden in AD1
. In het tweede geval wordt de uitzondering niet verwerkt en AD1
wordt in plaats daarvan het standaardtoepassingsdomein gebruikt.
Notitie
De naam van het standaardtoepassingsdomein is hetzelfde als de naam van het uitvoerbare bestand.
Als u een handler voor de FirstChanceException gebeurtenis toevoegt aan het standaardtoepassingsdomein, wordt de gebeurtenis gegenereerd en afgehandeld voordat het standaardtoepassingsdomein de uitzondering afhandelt. Als u dit wilt zien, voegt u de C#-code AppDomain.CurrentDomain.FirstChanceException += FirstChanceException;
(in Visual Basic, AddHandler AppDomain.CurrentDomain.FirstChanceException, FirstChanceException
) toe aan het begin van Main()
.
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 {0}: {1}",
AppDomain.CurrentDomain.FriendlyName, ex.Message);
}
}
static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e)
{
Console.WriteLine("FirstChanceException event raised in {0}: {1}",
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 {0}: {1}",
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