2010-03-25 15 views
5

Używam tego kodu C# w Visual Studio w trybie debug:Dlaczego program Visual Studio nie wyświetla komunikatu wyjątku, gdy mój wyjątek wystąpi w konstruktorze statycznym?

public class MyHandlerFactory : IHttpHandlerFactory 
{ 
    private static Dictionary<string, bool> myDictionary = new Dictionary<string, bool>(); 
    static MyHandlerFactory() 
    { 
    myDictionary.Add("someKey",true); 
    myDictionary.Add("someKey",true); // fails due to duplicate key 
    } 
} 

Outside of statycznym konstruktorze, kiedy się do linii z błędem Visual Studio podkreśla go i wyskakuje komunikat o wyjątku . Ale w konstruktorze statycznym nie otrzymuję takiej wiadomości. Przechodzę line-by-line, więc wiem, że idę do tej linii i nie dalej.

Dlaczego tak jest?

(nie mam pojęcia, czy fakt, że moja klasa implementuje spraw IHttpHandlerFactory, ale włączyła ją na wszelki wypadek).

To VS2005, .NET 2.0

Edit: Chcę tylko dodać, fakt, że jest to HttpHandler ma wydaje się mieć znaczenie. Jak wskazały odpowiedzi, domyślnym zachowaniem jest złamanie wyjątku TypeInitializationException, a nie wewnętrznego wyjątku. Przetestowałem inny przykład bez HttpHandler i zobaczyłem, że spowodowało to złamanie programu w pierwszym wierszu, który używał tej klasy. Ale w tym przypadku nie ma linii w moim kodzie do włamania, ponieważ klasa została wywołana tylko jako HttpHandler określony w moim pliku web.config. W związku z tym nie przerwał on wcale wyjątku.

Odpowiedz

9

Problem polega na tym, że zgłoszony wyjątek jest w rzeczywistości wyjątkiem TypeInitializationException, który zawiera wyjątek. Nie jestem pewien, co spowodowało to kompromisy w zakresie projektowania, ale IMO to jedna z najbardziej irytujących rzeczy w rozwoju .NET i smutno mi, że nadal jest w .NET 4.

W VS, aby złapać wyjątek JAK NAJSZYBCIEJ, musisz włączyć wyjątki pierwszej szansy. Przejdź do Debugowanie> Wyjątki i zaznacz "Wyjątki środowiska wykonawczego języka wspólnego", które zostaną zerwane zaraz po zgłoszeniu wyjątku.

(Uwaga: jeśli korzystasz z Dynamic Language Runtime, musisz być bardziej wybredny, jeśli chodzi o wyjątki, ponieważ najwyraźniej używa wyjątków do kontroli przepływu).

+0

Dzięki za odpowiedź. Jednak opcje widoczne w sekcji Debug> Exceptions ... to "Wyjątki C++", "Wyjątki środowiska wykonawczego języka wspólnego", "Managed Debugging Assistants", "Native Run-Time Checks" i "Win32 Exceptions". Czy ".NET Exceptions" jest pod jednym z tych? Nie mogłem go znaleźć. –

+0

@Tim Goodman - OOPS! Miałem na myśli "Wyjątki środowiska wykonawczego języka wspólnego". Zaktualizuję moją odpowiedź. –

+0

Ach tak, powodując przerwanie, gdy wyrzucane są wyjątki środowiska wykonawczego języka wspólnego, spowodowało złamanie wewnętrznego wyjątku. Dzięki. –

1

Próbowałem twój kod i dostałem wyjątek TypeInitializationException zgodnie z oczekiwaniami. Nie ma problemu w moim VS ...

Ale jeśli uruchomisz tę (lub dowolną inną) aplikację "bez debugowania", zawsze powinieneś otrzymać komunikat o błędzie dla nieobsługiwanych wyjątków - żadne ustawienia VS nie wprowadzą tutaj żadnej różnicy.

+0

Na jakiej linii otrzymałeś wyjątek TypeInitializationException? Myślę teraz, że problem polega na tym, że normalnie wystąpiłby błąd w pierwszym wierszu, aby odwołać się do klasy (tej, która powoduje wywołanie konstruktora statycznego), ale w tym przypadku jest ona wywoływana jako HttpHandler, więc nie ma linii do iść do. –

+0

Wyjątek TypeInitializationEx pojawia się w wierszu, w którym utworzę nowe wystąpienie klasy: Fabryka MyHandlerFactory = new MyHandlerFactory(); Ale spróbowałem bez interfejsu, z którego pochodzi. Być może mógłbyś rozszerzyć próbkę, którą moglibyśmy przetestować exatly tak jak w twoim kodzie. – Machta

+0

Zdarzyło mi się, że dzisiaj znowu patrzę na to siedmioletnie pytanie, więc pomyślałem, że spóźniłam się na odpowiedź. :) W celu odtworzenia problemu uważam, że konieczne było zarejestrowanie Handler'a HTTP w Web.config aplikacji internetowej ASP.NET (zobacz tutaj: https://msdn.microsoft.com/en-us/library/46c5ddfy. aspx) i uzyskać do niego dostęp, próbując załadować stronę aplikacji internetowej. –

0

Konstruktor statyczny zostanie uruchomiony przed uruchomieniem aplikacji w domenie aplikacji. To prawdopodobnie powoduje problemy ze sposobem, w jaki VS łapie wyjątek, który z twojego opisu jest dość niestandardowy. Może to być ograniczenie roku 2005. Dlatego zawsze należy łapać w ciele konstruktora statycznego. Istnieje doskonała dyskusja na ten temat w nowej książce Effective C#

Powiązane problemy