2011-02-10 20 views
5

Czy ktoś może mi wyjaśnić, dlaczego nie mogę rzucić wyjątku z wnętrza zdarzenia AppDomain.Assembly? Na przykład:Wyrzucanie wyjątków z zdarzenia 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(); 
    } 
} 

Kiedy wykonać to, wyjście jest w następujący sposób:

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

Może ktoś wyjaśnić ten problem do mnie? Dziękuję Ci.

EDIT Aby wyjaśnić kilka rzeczy:

  • Impreza obciążenie montaż przebiega w porządku, kiedy spodziewać się go uruchomić. Ale mój wyjątek nigdy nie zostanie rzucony.

  • To jest destylowany przykład zaczerpnięty z większej aplikacji. Chcę sprawdzić zespół po jego załadowaniu, a jeśli nie podoba mi się coś o niej, chcę szybko uda ... Ale mój wyjątek nie „zdarzyć”

+0

Czy używasz maszyny 64-bitowej? Miałem bardzo podobne ar problem. Zobacz: http://stackoverflow.com/questions/4125876/what-happens-when-you-attempt-to-access-a-informations-treeview-by-keyword-and-that-k/4125994#4125994 – Crisfole

+0

@Cpfohl : Dzięki, jestem na x64, ale moim celem na platformie jest już x86 ... – TheNextman

+0

Tak czy inaczej ma to sens, ponieważ błąd dotyczy ładowania formularzy, a nie ogólnego ładowania. – Crisfole

Odpowiedz

1

Dlaczego uważasz, że wyjątek Jeśli nie został rzucony, można by oczekiwać, że wyświetli się komunikat "Nie powinno się nigdy tu być ...", ale ponieważ go nie ma, wyjątek prawdopodobnie jest wyrzucany

Twój kod nie łowienie wyjątkiem jest zupełnie inna historia.Może to całkiem możliwe, że kod, który podnosi zdarzenie AppDomain.AssemblyLoad jest wychwytywanie wyjątków

+0

Tak, masz rację: oczywiście mój wyjątek został rzucony (na podstawie nie wykonanej drugiej konsoli Console.WriteLine). Wygląda na to, że ktoś wyżej zajmuje się wyjątkiem. – TheNextman

+0

Zatem następnym logicznym pytaniem jest, dlaczego jest on złapany? Microsoft ma bardzo mocne stanowisko w sprawie zapewnienia, że ​​wyjątki zawsze będą propagować w swoich licencjach BCL, jeśli nie będą obsługiwane. – Tyson

+0

@Tyson: wyjątek wydaje się być spożywane przez CLR, a nie BCL. Co do tego, dlaczego został on złapany, nie jestem świadomy żadnej dokumentacji, która rozwiązuje ten problem w jakikolwiek sposób. –

1

Dzieje się tak ze względu na sposób działania kompilatora JIT. Musi wygenerować kod dla metody Main(), zanim będzie mógł zacząć działać. Ponieważ odwołujesz się do typu ClassLibrary1.Class1(), musi on załadować ten zespół, aby pobrać informacje o typie. Wymaga to załadowania zespołu przed uruchomieniem kodu. Zmienić go tak, aby uzyskać wyjątek:

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(); 
    } 

Teraz statyczny konstruktor może działać pierwszy i zarejestrować obsługi zdarzeń AssemblyLoad zanim zespół ClassLibrary1 zostanie załadowany.

+0

Dzięki, ale to nie działa ... Wynik jest taki sam. – TheNextman

0

Wydaje mi się, że zdarzenie dotyczące obciążenia złożenia ma miejsce w oddzielnym wątku, używając asynccback. Nie otrzymujesz wyjątku, ponieważ musisz użyć aplikacji Application.ThreadException + = new System.Threading.ThreadExceptionEventHandler (Application_ThreadException);

myślę, że nie jestem ekspertem w tej sprawie w ogóle

1

Wyjątkiem jest wyrzucane. Ale wygląda na to, że .NET czasami ignoruje wyjątki występujące podczas uruchamiania (Main()). Nie jestem pewien przyczyny, ale zwykle przejdź do Debug-> Exceptions i zaznacz pole "Throw" dla wyjątków Runtime Common Language ", aby móc złamać wyjątek."

+0

Tak, masz rację.Wyjątek jest generowany przy założeniu, że włączono funkcję VS, aby włamać się do wyrzucanych wyjątków ... Jednak wykonanie jest kontynuowane. – TheNextman

Powiązane problemy