Este artículo se tradujo automáticamente. Para ver el artículo en inglés, active la casilla Inglés. Además, puede mostrar el texto en inglés en una ventana emergente si mueve el puntero del mouse sobre el texto.
Traducción
Inglés

Evento AppDomain.FirstChanceException

.NET Framework (current version)
 

Publicado: noviembre de 2016

Ocurre cuando se produce una excepción en código administrado, antes de que el runtime busque un controlador de excepciones en la pila de llamadas del dominio de aplicación.

Espacio de nombres:   System
Ensamblado:  mscorlib (en mscorlib.dll)

public event EventHandler<FirstChanceExceptionEventArgs> FirstChanceException

Este evento es solo una notificación. Controlar este evento no controla la excepción ni afecta a la de ninguna manera de control de excepciones posterior. Después de que se ha producido el evento y controladores de eventos se ha invocado, common language runtime (CLR) comienza a buscar un controlador para la excepción. FirstChanceExceptionproporciona el dominio de aplicación con una primera oportunidad para examinar cualquier excepción administrada.

El evento se puede administrar por dominio de aplicación. Si un subproceso pasa a través de varios dominios de aplicación mientras se ejecuta una llamada, el evento se produce en cada dominio de aplicación que ha registrado un controlador de eventos antes de que el CLR comienza a buscar un controlador de excepción coincidente en ese dominio de aplicación. Después de que se ha controlado el evento, se realizará una búsqueda de un controlador de excepción coincidente en ese dominio de aplicación. Si no se encuentra ninguno, se produce el evento en el siguiente dominio de aplicación.

Debe controlar todas las excepciones que se producen en el evento controlador para el FirstChanceException eventos. En caso contrario, FirstChanceException es generado de forma recursiva. Esto podría resultar en un desbordamiento de pila y la finalización de la aplicación. Se recomienda implementar controladores de eventos para este evento como regiones de ejecución restringida (CER), para impedir que las excepciones relacionadas con la infraestructura, como memoria insuficiente o desbordamiento de pila que afectan a la máquina virtual mientras se procesa la notificación de excepción.

Este evento no se desencadena para las excepciones que indican los daños del estado de proceso, como las infracciones de acceso, a menos que el controlador de eventos es crítico para la seguridad y tiene el HandleProcessCorruptedStateExceptionsAttribute atributo.

Common language runtime suspende las anulaciones de subprocesos mientras se está controlando este evento de notificación.

En el ejemplo siguiente se crea una serie de dominios de aplicación denominado AD0 a través de AD3, con un Worker objeto en cada dominio de aplicación. Cada Worker objeto tiene una referencia a la Worker objeto en el siguiente dominio de aplicación, excepto el Worker en el último dominio de aplicación. El FirstChanceException evento está controlado en todos los dominios de aplicación excepto AD1.

System_CAPS_noteNota

Además de este ejemplo, que muestra las notificaciones de excepciones de primera oportunidad en varios dominios de aplicación, puede encontrar casos de uso sencillo en Cómo: Recibir notificaciones de excepciones de primera oportunidad.

Cuando se hayan creado los dominios de aplicación, el dominio de aplicación predeterminado llama el TestException método para el primer dominio de aplicación. Cada Worker objeto llama el TestException método para el dominio de aplicación siguiente, hasta el último Worker produce una excepción que es controlada o no. Por lo tanto, el subproceso actual se pasa a través de todos los dominios de aplicación, y TestException se agrega a la pila en cada dominio de aplicación.

Cuando el último Worker objeto controla la excepción, el FirstChanceException evento se produce solo en el último dominio de aplicación. Los demás dominios de aplicación nunca tienen la oportunidad para controlar la excepción, por lo que no se genera el evento.

Cuando el último Worker objeto no controla la excepción, el FirstChanceException evento se produce en cada dominio de aplicación que tiene un controlador de eventos. Una vez finalizada cada controlador de eventos, la pila continúa desenredar hasta que se detecta la excepción por dominio de aplicación predeterminado.

System_CAPS_noteNota

Para ver cómo la presentación de la pila crece tal y como se genera el evento más cercano y cuanto más se acerque al dominio de aplicación predeterminado, cambie e.Exception.Message a e.Exception en el FirstChanceHandler controladores de eventos. Tenga en cuenta que, cuando TestException se llama a través de los límites del dominio de aplicación, este aparece dos veces: una vez para el proxy y otra para el código auxiliar.

using System;
using System.Reflection;
using System.Runtime.ExceptionServices;

class Example
{
    static void Main()
    {
        AppDomain.CurrentDomain.FirstChanceException += FirstChanceHandler;

        // Create a set of application domains, with a Worker object in each one.
        // Each Worker object creates the next application domain.
        AppDomain ad = AppDomain.CreateDomain("AD0");
        Worker w = (Worker) ad.CreateInstanceAndUnwrap(
                                typeof(Worker).Assembly.FullName, "Worker");
        w.Initialize(0, 3);

        Console.WriteLine("\r\nThe last application domain throws an exception and catches it:");
        Console.WriteLine();
        w.TestException(true);

        try
        {
            Console.WriteLine(
                "\r\nThe last application domain throws an exception and does not catch it:");
            Console.WriteLine();
            w.TestException(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
{
    private AppDomain ad = null;
    private Worker w = null;

    public void Initialize(int count, int max)
    {
        // Handle the FirstChanceException event in all application domains except
        // AD1.
        if (count != 1)
        {
            AppDomain.CurrentDomain.FirstChanceException += FirstChanceHandler;
        }

        // Create another application domain, until the maximum is reached.
        // Field w remains null in the last application domain, as a signal
        // to TestException(). 
        if (count < max)
        {
            int next = count + 1;
            ad = AppDomain.CreateDomain("AD" + next);
            w = (Worker) ad.CreateInstanceAndUnwrap(
                             typeof(Worker).Assembly.FullName, "Worker");
            w.Initialize(next, max);
        }
    }

    public void TestException(bool handled)
    {
        // As long as there is another application domain, call TestException() on
        // its Worker object. When the last application domain is reached, throw a
        // handled or unhandled exception.
        if (w != null)
        {
            w.TestException(handled);
        }
        else if (handled)
        {
            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);
        }
    }

    static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e)
    {
        Console.WriteLine("FirstChanceException event raised in {0}: {1}",
            AppDomain.CurrentDomain.FriendlyName, e.Exception.Message);
    }
}

/* This example produces output similar to the following:

The last application domain throws an exception and catches it:

FirstChanceException event raised in AD3: Thrown in AD3
ArgumentException caught in AD3: Thrown in AD3

The last application domain throws an exception and does not catch it:

FirstChanceException event raised in AD3: Thrown in AD3
FirstChanceException event raised in AD2: Thrown in AD3
FirstChanceException event raised in AD0: Thrown in AD3
FirstChanceException event raised in Example.exe: Thrown in AD3
ArgumentException caught in Example.exe: Thrown in AD3
 */

SecurityCriticalAttribute

Requires full trust for the immediate caller. This member cannot be used by partially trusted or transparent code.

.NET Framework
Disponible desde 4.0
Volver al principio
Mostrar: