2011-02-10 13 views
5

¿Puede alguien explicarme por qué no puedo lanzar una excepción desde dentro del evento AppDomain.Assembly load? Por ejemplo:Lanzar una excepción desde el evento AppDomain.AssemblyLoad

class Program 
{ 
    static Program() 
    { 
     AppDomain.CurrentDomain.UnhandledException += (s, a) => 
     { 
      Console.WriteLine("Caught exception!"); 
     }; 

     AppDomain.CurrentDomain.AssemblyLoad += (s, a) => 
     { 
      Console.WriteLine(string.Format("Assembly {0} loaded", a.LoadedAssembly.FullName)); 

      throw new Exception(); 

      Console.WriteLine("Should never get here..."); 
     }; 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine(new ClassLibrary1.Class1().TestString()); 
     Console.WriteLine(); 
     Console.WriteLine("Done..."); 
     Console.ReadLine(); 
    } 
} 

Cuando ejecuto esto, la salida es la siguiente:

Assembly ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null loaded 
TestString 
Done... 

Puede alguien explicar este comportamiento conmigo? Gracias.

EDITAR Para aclarar un par de cosas:

  • El evento de carga de montaje funciona muy bien, cuando yo esperaba que se ejecute. Pero mi excepción nunca se arroja

  • Este es un ejemplo destilado tomado de una aplicación más grande. Quiero inspeccionar el montaje después de que se carga y si no me gusta algo al respecto, quiero fallar rápido ... Pero mi excepción no 'da la casualidad'

+0

¿Está ejecutando en una máquina de 64 bits? Tenía una muy similar ar problema. Ver: http://stackoverflow.com/questions/4125876/what-happens-when-you-attempt-to-access-a-winforms-treeview-by-keyword-and-that-k/4125994#4125994 – Crisfole

+0

@Cpfohl : Gracias, estoy en x64 pero mi objetivo de plataforma ya es x86 ... – TheNextman

+0

En realidad, eso tiene sentido de todos modos, ya que el error es para la carga de formularios, no para la carga general. – Crisfole

Respuesta

1

¿Por qué cree que la excepción Si no se lanzara, se esperaría ver su salida "Nunca debería llegar ...". Sin embargo, dado que no está allí, la excepción presumiblemente se está lanzando.

Su código no capturando la excepción es otra historia. Es muy posible que el código que genera el evento AppDomain.AssemblyLoad está capturando excepciones.

+0

Sí, tiene razón: por supuesto, mi excepción fue lanzada (en base a la segunda Console.WriteLine no se está ejecutando). Parece que alguien más arriba está manejando la excepción. – TheNextman

+0

Entonces, la siguiente pregunta lógica es ¿por qué se está atrapando? Microsoft tiene una postura muy firme para garantizar que las excepciones siempre se propaguen en sus BCL si no se administran. – Tyson

+0

@ Tyson: La excepción parece ser consumida por el CLR, no el BCL. En cuanto a por qué está siendo atrapado, no conozco ninguna documentación que aborde este tema de ninguna manera. –

1

Esto sucede debido a la forma en que funciona el compilador JIT. Necesita generar el código para el método Main() antes de que pueda comenzar a ejecutarse. Como hace referencia al tipo ClassLibrary1.Class1(), necesita cargar ese ensamblado para recuperar la información de tipo. Eso requiere que cargue el ensamblaje antes de, su código comienza a ejecutarse. Cambiarlo como este para obtener la excepción:

using System.Runtime.CompilerServices; 
... 
    static void Main(string[] args) { 
     Test(); 
    } 
    [MethodImpl(MethodImplOptions.NoInlining)] 
    static void Test() { 
     Console.WriteLine(new ClassLibrary1.Class1().TestString()); 
     Console.WriteLine(); 
     Console.WriteLine("Done..."); 
     Console.ReadLine(); 
    } 

Ahora el constructor estático puede ejecutar primero y registrar el controlador de eventos AssemblyLoad ante la asamblea ClassLibrary1 se carga.

+0

Gracias pero esto no parece funcionar ... El resultado es el mismo. – TheNextman

0

Creo que el evento de carga de ensamblaje se está produciendo en un subproceso separado, utilizando asynccallback. No obtiene la excepción porque necesita usar Application.ThreadException + = new System.Threading.ThreadExceptionEventHandler (Application_ThreadException);

creo, no soy un experto en esto en absoluto

1

se produce la excepción. Pero parece que .Net a veces ignora las excepciones que suceden en el inicio (Main()). No estoy seguro de la razón, pero normalmente voy a Depurar-> Excepciones y marque la casilla "Lanzar" para excepciones de Common Language Runtime "para poder romper la excepción.

+0

Sí, tienes razón.La excepción se produce suponiendo que habilité VS para romper excepciones lanzadas ... Pero la ejecución continúa de todos modos. – TheNextman

Cuestiones relacionadas