Delen via


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

  1. 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
    
  2. 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
    
  3. 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

  1. 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
    
  2. 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 eigenschap Main() (Sharedin Visual Basic) AppDomain.CurrentDomain om een verwijzing naar het standaardtoepassingsdomein op te halen.

Uitzonderingsmeldingen voor de eerste kans demonstreren in het toepassingsdomein

  1. Maak een Worker object in het toepassingsdomein dat u in de vorige procedure hebt gemaakt. De Worker 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)
    
  2. Roep een methode aan van het Worker object dat een uitzondering genereert. In dit voorbeeld wordt de Thrower methode twee keer aangeroepen. De eerste keer is truehet methodeargument, wat ervoor zorgt dat de methode een eigen uitzondering ondervangt. De tweede keer is falsehet argument en de Main() 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
    
  3. 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 AD1genereert, wordt de FirstChanceException gebeurtenis gegenereerd in AD1en 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 AD1wordt 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

Zie ook