2010-05-10 14 views
7

OK, admito que este código solo se verá raro para usted, y es porque es extraño. Esto es solo código para reproducir el comportamiento, no el código que quiero usar.No se puede detectar la excepción de Activator.CreateInstance

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      Activator.CreateInstance(typeof(Func<int>), new object[] { new object(), IntPtr.Zero }); 
     } 
     catch 
     { 
      Console.WriteLine("This won't print!"); 
     } 

     Console.Write("Actually this will not print either!"); 
     Console.ReadLine(); 
    } 
} 

No importa qué tipo de excepción Trato de coger (la excepción real emitida es un ArgumentException la medida de lo que puedo decir) el código dentro del bloque catch no se ejecutará. En realidad, la ejecución se detendrá en Activator.CreateInstance-line.

+0

¿Esto solo ocurre al construir delegados? Se supone que debes usar 'Delegate.CreateDelegate' para eso. –

+0

Probablemente solo ocurra al construir delegados, pero el código real donde se usa esto no es consciente de qué tipo está intentando crear, la solución ahora es que está "prohibido" siquiera intentar si el tipo hereda de Delegate. –

Respuesta

4

Usted ha bombardeado el CLR con ese código. Impresionante. El contratiempo real es la corrupción del montón recogido de basura, se señaliza con ExecutionEngineException. Aparentemente, el daño es lo suficientemente extenso como para evitar que el CLR ejecute el manejador de excepciones.

Puede informar esto en connect.microsoft.com. Sin embargo, el error se corrigió en .NET 4.0, genera la excepción adecuada, ArgumentNullException, "El valor no puede ser nulo, nombre del parámetro: método". La solución es obvia, no pase IntPtr.Zero cuando espera una cadena no nula.

1

Cuando ejecuto este código en .NET 3.5 obtengo un ExecutionEngineException. Cuando el tiempo de ejecución arroja esta excepción, es similar a llamar al Environment.FailFast. Aparentemente, este es un síntoma de corrupción de memoria en el montón.

Cuando cambio su código de ejemplo a lo siguiente, se logra el comportamiento correcto.

Activator.CreateInstance(
    typeof(Func<int>), 
    new object[] { IntPtr.Zero, new object() } 
); 

soy muy consciente de que esto nos lleva a más preguntas que respuestas ... :)

+0

No puedo detectar la excepción e inspeccionarla en absoluto, ¿cuál es su configuración para lograr esto? –

+0

@Patrik - ¿Qué versión de .NET está ejecutando? – ChaosPandion

+0

3.5 usando VS 2008. –

Cuestiones relacionadas