Program Visual Studio 2015 przerwa w przypadku nieobsługiwanych wyjątków, które nie działają

114

W programie Visual Studio było kiedyś określone pole wyboru „Przerwij w przypadku nieobsługiwanego wyjątku”. W 2015 roku został on usunięty (lub przeniesiony w miejsce, w którym nie mogę go znaleźć). Więc teraz moje przekonwertowane projekty nie psują się, jeśli nie uda mi się zapewnić obsługi wyjątków na poziomie użytkownika. Nie chcę przerywać wszystkich „wyrzuconych wyjątków”, ponieważ obsługuję określone. Właśnie tam, gdzie nie mogę podać konkretnego programu obsługi.

W tej chwili mój kod po prostu wychodzi z bieżącej procedury i kontynuuje wykonywanie w następnej lokalizacji stosu wywołań, NIE DOBRY.

Czy ktoś wie, jak odzyskać to w programie Visual Studio 2015? Właśnie wczoraj uaktualniłem do wersji społecznościowej.

Ted Lowery
źródło
Program Visual Studio 2015 zachowa bieżący układ z poprzedniej wersji, jeśli karta Toollub nie Windowbędzie zawierała wszystkich żądanych lokalizacji. W twoim przypadku szukasz ustawień wyjątków .
Greg,
4
@greg, to nie tak, że nie wiem, gdzie znaleźć panel. Martwię się, że zachowanie, którego szukam, nie znajduje się w tym panelu.
Ted Lowery,
mam ten sam problem. W naszym przypadku spodziewamy się przerwania wyjątku, gdy autofac nie ma zarejestrowanych wszystkich typów. Używając tego samego rozwiązania z vs2013 działa, w vs2015 nic nie dostajemy. jest to również problem z rejestracjami i wyjątkami innych firm zewnętrznych (np. nservicebus) Zastanawiam się, czy dotyczy to tylko projektu utworzonego w vs2013 i uruchomionego w vs2015
Choco Smith
3
To nowe okno narzędzi jest naprawdę do bani.
cedd
Zgodnie z klasyfikacjami wyjątków MS, jeśli masz nieobsługiwany wyjątek, zawsze uszkadza debugger. Może być konieczne zaznaczenie opcji „Przerwij, gdy fragmenty przekroczą domenę aplikacji ...” na liście „Opcje -> Debugowanie -> Ogólne”.
tsul

Odpowiedzi:

118

Pojawiło się nowe okno o nazwie „Ustawienia wyjątków”, które pojawia się domyślnie w prawym dolnym okienku po rozpoczęciu debugowania. Ma wszystkie opcje, których można się spodziewać.

Możesz to wywołać za pomocą CTRL+ ALT+E

Pozwala to na najlepszy wybór wyjątków powodujących przerwę w debugerze.

Kluczowe jest jednak to, że możesz również ustawić, czy te wyjątki zawsze się psują, czy tylko wtedy, gdy jest to nieobsługiwany wyjątek - ale ustawienie tego nie jest zbyt intuicyjne.

Najpierw musisz zaznaczyć „Włącz tylko mój kod” w menu Narzędzia> Opcje> Debugowanie.

Dzięki temu można kliknąć prawym przyciskiem myszy nagłówek kolumny (Przerwij po zgłoszeniu) w nowym oknie Ustawienia wyjątków i dodać kolumnę „Dodatkowe działania”, która następnie umożliwia ustawienie każdego wyjątku jako „Kontynuuj, gdy nie jest obsługiwany w kodzie użytkownika”.

Po prostu kliknij prawym przyciskiem myszy wyjątek lub całą grupę i wyłącz flagę „Kontynuuj, gdy nie jest obsługiwana w kodzie użytkownika”. Niestety, kolumna „Dodatkowe akcje” będzie pusta, co jest tym samym, co „Przerwij po nieobsługiwaniu w kodzie użytkownika”.

wprowadź opis obrazu tutaj

Więcej na ten temat tutaj:

http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx

Tom Studee
źródło
7
Właściwie to okno ma tylko opcje „zerwania z wyrzuceniem”. Nie tego chcę. Chcę „złamać, gdy nie jest obsługiwany”.
Ted Lowery,
17
i to jest problem. NIE pęka. jak powiedziałem powyżej, wychodzi (wychodzi) z bieżącego wywołania procedury i po prostu rozpoczyna wykonywanie następnego wiersza kodu w procedurze wywołującej.
Ted Lowery,
2
i mam włączoną opcję „Tylko mój kod”.
Ted Lowery,
19
@TomStudee Ja też mam ten sam problem. To, czego chcę, to „Złamanie po nieużywaniu”, ale otrzymuję „Złamanie po rzuceniu”. Pytanie brzmi: jak uzyskać „Break when unhandled”?
ogggre
1
@TomStudee Właśnie dodałem kilka bardzo potrzebnych wyjaśnień, ponieważ brakowało Ci ustawienia klucza, które pozwala ustawić wyjątki tak, aby łamały się tylko wtedy, gdy nie są obsługiwane.
Jerad Rose
36

Miałem ten sam problem i udało mi się go rozwiązać, robiąc to -

  1. Naciśnij Ctrl+ Alt+, eaby wyświetlić okno Ustawienia wyjątków .
  2. Zaznacz opcję Wyjątki środowiska wykonawczego języka wspólnego . wprowadź opis obrazu tutaj

Otóż ​​to!

Zainspirował mnie ten post, ponieważ używam wersji x64 systemu Windows .

Justin XL
źródło
7
Spowoduje to zerwanie wszystkich wyjątków, nawet tych obsługiwanych przez kod użytkownika.
carlin.scott
1
@ carlin.scott, myślę, że możesz ręcznie odznaczyć obsługiwane wyjątki z listy.
Justin XL
6
@JustinXL Problem polega na tym, że jest to lista według typu wyjątków, a nie według tego, czy jest obsługiwana, czy nie. Na przykład są chwile, kiedy System.ArgumentExceptionjest obsługiwany, i chwile, kiedy nie. I tylko o łamanie kiedy to nie obchodzić.
Jerad Rose
1
@JeradRose Debuger zawsze się zepsuje, gdy wyjątek nie zostanie obsłużony. Tak jak powiedziałem, jeśli nie chcesz przerywać obsługi wyjątków, po prostu odznacz te typy wyjątków z listy Break When Thrown .
Justin XL,
Nawet sprawdzając wszystko, nie psuje się na wyjątku: / po prostu wychodzę
Douglas Gaskell
10

Dla pracowników Google, którzy chcą się zepsuć tylko wtedy, gdy wyjątek dotyczy ich kodu, w programie Visual Studio 2015 dostępna jest opcja: Opcje-> Debugowanie-> Ogólne-> Tylko mój kod. Po zaznaczeniu pozwala nie przerywać, gdy wyjątek jest zarządzany (zgłaszany i przechwytywany) poza kodem.

Olivier de Rivoyre
źródło
Uratowało mnie to przed kolejną sytuacją, w której VS2015 z jakiegoś powodu odmówił wprowadzenia jakiegoś kodu. Kod jest „mój”, ale coś wyzwoliło flagę „Tylko mój kod”. Wydaje mi się, że jest gdzieś błąd podczas uruchamiania 2 instancji VS i samodzielnego serwera WWW i prawdopodobnie więcej.
LosManos
9

Microsoft subtelnie zmienił logikę w nowym oknie wyjątków.

Zobacz http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx

Kluczowa część to:

Ważne notatki

  • To nowe okno zawiera wszystkie te same funkcje, co stare okno modalne. Żadne możliwości debugera nie zmieniły się tylko w sposobie uzyskania do nich dostępu
  • Debuger zawsze się zepsuje, gdy wyjątek nie zostanie obsłużony
  • Ustawienie, które ma zostać zmienione, jeśli debuger przerwie się w przypadku wyjątków nieobsługiwanych przez użytkownika, zostało przeniesione do menu kontekstowego
  • Lokalizacja menu została przeniesiona do Debug -> Windows -> Ustawienia wyjątków

Jeśli jednak tak jak ja masz w swoim kodzie Global Unhandled Exception Handler, to druga pozycja na tej liście jest kluczowa: dla mnie żadne wyjątki nie będą więc naprawdę nieobsługiwane, co wydaje się różnić od VS2013.

Aby powrócić do zachowania, w którym VS przerywa nieobsłużone wyjątki, musiałem zaznaczyć wszystkie typy wyjątków, dla których chciałem przerwać, a następnie upewnić się, że „Dodatkowe opcje” (może być konieczne, aby ta kolumna była widoczna *) dla „Kontynuuj gdy nieobsługiwane w kodzie użytkownika ” NIE zostało ustawione. Wydaje się, że logika VS2015 nie uważa, że ​​mój program obsługi globalnych nieobsługiwanych wyjątków jest „obsługiwany w kodzie użytkownika”, więc nie działa na nich; nie psuje się jednak na złapanych wyjątkach. To sprawia, że ​​działa tak, jak zrobił to VS2013.

* Jak włączyć kolumnę „Dodatkowe działania” * Jak włączyć kolumnę „Dodatkowe działania”

oatsoda
źródło
2
Nie działa to dokładnie tak, jak VS2013, ponieważ zepsuje się w przypadku wyjątków obsługiwanych przez użytkownika z zasugerowanymi ustawieniami, co nie miało miejsca w przeszłości.
carlin.scott
Jak wyświetlić kolumnę „Dodatkowe opcje”?
UuDdLrLrSs
@DaveInCaz Kliknij prawym przyciskiem myszy nagłówek kolumny> „Pokaż kolumny”> „Dodatkowe działania”
oatsoda
7

Jeśli poprawnie czytam między wierszami w tym miejscu, problem polega na tym, że Twój wyjątek skutecznie `` znika '', mimo że domyślne zachowanie debugera powinno zostać przerwane w przypadku nieobsłużonych wyjątków.

Jeśli masz metody asynchroniczne, możesz napotkać ten problem, ponieważ wyjątki, które nie zostały przechwycone w wątku puli wątków jako część kontynuacji zadania, nie są uznawane za nieobsłużone wyjątki. Są raczej połykane i przechowywane wraz z Zadaniem.

Na przykład spójrz na ten kod:

class Program
{
    static void Main(string[] args)
    {
        Test();
        Console.ReadLine();
    }

    private async static Task Test()
    {
        await Task.Delay(100);
        throw new Exception("Exception!");
    }
}

Jeśli uruchomisz ten program z domyślnymi ustawieniami debugera (zatrzymaj tylko w przypadku nieobsługiwanych wyjątków), debuger nie ulegnie awarii. Dzieje się tak, ponieważ wątek puli wątków przydzielony do kontynuacji połyka wyjątek (przekazując go do wystąpienia zadania) i zwalnia się z powrotem do puli.

Zauważ, że w tym przypadku prawdziwym problemem jest to, że Taskzwracany przez Test()nigdy nie jest sprawdzany. Jeśli masz podobny typ logiki „wystrzel i zapomnij” w swoim kodzie, nie zobaczysz wyjątków w momencie ich wyrzucenia (nawet jeśli są one „nieobsługiwane” w metodzie); wyjątek pojawia się tylko wtedy, gdy obserwujesz zadanie, czekając na nie, sprawdzając jego wynik lub jawnie patrząc na jego wyjątek.

To tylko przypuszczenie, ale myślę, że prawdopodobnie obserwujesz coś takiego.

Dan Bryant
źródło
Chociaż może to nie być związane z problemem operacji, pojawia się bardzo dobry punkt na temat wyjątków zgłaszanych w procedurach asynchronicznych.
Phil Cooper
Czy istnieje sposób na zatrzymanie debugera, mimo że wyjątek jest przechowywany w ten sposób?
Lucas
@Lucas, Nie jestem tego świadomy, chociaż możesz zbliżyć się do niektórych zmian w kodzie. Jeśli treść metody uruchom i zapomnij zawiera blok try-catch, możesz dodać jawne Debugger.Break()wywołanie. Alternatywnie, można dodać wyraźne Debugger.Break()w TaskScheduler.UnobservedTaskExceptionobsługi, ale minusem jest to, że może to ogień znacznie później niż w oryginalnym wyjątku, jak to się dzieje na gwincie finalizatora kiedy zadanie zostanie oczyszczone. Ogólnie powinieneś starać się zawsze obserwować wyniki zadań lub przynajmniej mieć blok try-catch do rejestrowania w momencie niepowodzenia.
Dan Bryant
3

Z mojego doświadczenia wynika, że ​​ustawienia wyjątków w 2015 roku są całkowicie odrzucane, jeśli coś zmienisz.

Spodziewaj się, że jeśli dojdziesz do grupy nadrzędnej "CLR", nie powinieneś otrzymać żadnego przerywającego execpt dla unhandled. Zawsze będziesz przerywać, jeśli wyjątek nie zostanie obsłużony. Ale jeśli masz odznaczoną grupę CLR, kod wewnątrz try ... catch po prostu nie powinien powodować przerwy. Tak nie jest.

Rozwiązanie: W nowym przyborniku ustawień wyjątków kliknij prawym przyciskiem myszy i wybierz „Przywróć domyślne”. Taadaaaa ... Znowu zachowuje się normalnie. Teraz nie rób tego.

Clint StLaurent
źródło
1

Spróbuj postępować zgodnie z instrukcjami:

  1. W oknie Ustawienia wyjątków otwórz menu kontekstowe, klikając prawym przyciskiem myszy w oknie, a następnie wybierając opcję Pokaż kolumny. (Jeśli wyłączyłeś Tylko mój kod, nie zobaczysz tego polecenia).
  2. Powinieneś zobaczyć drugą kolumnę o nazwie Dodatkowe działania. W tej kolumnie wyświetla się Kontynuuj, gdy nie jest obsługiwany przez kod użytkownika dla określonych wyjątków, co oznacza, że ​​debuger nie przerywa, jeśli ten wyjątek nie jest obsługiwany w kodzie użytkownika, ale jest obsługiwany w kodzie zewnętrznym.
  3. Możesz zmienić to ustawienie dla konkretnego wyjątku (wybierz wyjątek, kliknij prawym przyciskiem myszy i zaznacz / usuń zaznaczenie opcji Kontynuuj, gdy nieobsługiwane w kodzie użytkownika) lub dla całej kategorii wyjątków (na przykład wszystkie wyjątki środowiska wykonawczego języka wspólnego).

https://msdn.microsoft.com/en-us/library/x85tt0dd.aspx

Andrei
źródło
Całkowicie się zgadzam. To okropne, aby domyślnie nie wyświetlać tej kolumny. Spędził dużo czasu, aby go znaleźć. Poza tym, co oznacza „ wyjątek nieobsługiwany przez użytkownika ”, jest raczej niejasne. Mój program obsługi anulowania zadania (coś podobnego try { task.Wait(); } catch { ... }) i wyjątek OperationCanceledException w zadaniu został uznany za nieobsługiwany w kodzie użytkownika.
tsul
1

To wszystko jest trochę zagmatwane i moim zdaniem nie tak dobre, jak stare okno dialogowe wyjątków, ale w każdym razie.

Jeśli wyjątek znajduje się na liście i jest zaznaczony, debuger zostanie przerwany za każdym razem, gdy zostanie zgłoszony wyjątek.

Jeśli wyjątek nie jest zaznaczony lub nie ma go na liście, debuger przerwie tylko wtedy, gdy ten typ wyjątku jest nieobsługiwany przez użytkownika.

Na przykład na poniższym zrzucie ekranu debugger zepsuje się za każdym razem, gdy System.AccessViolationExceptionzostanie wyrzucony a, ale w przypadku wszystkich innych wyjątków będzie działać tylko wtedy, gdy wyjątek nie został obsłużony przez użytkownika.

Okno narzędzia Wyjątki programu Visual Studio 2015

cedd
źródło
1

Po uaktualnieniu do VS2015 miałem również problemy polegające na tym, że wyjątki kiedyś „łamały” aplikację, ale teraz są ignorowane i od razu pomijane. Są chwile, kiedy chcemy, aby nasz kod celowo generował wyjątki w miejscach, w których chcemy, aby kod zatrzymywał się zamiast kontynuować. Zawsze używamy tego wyrażenia, Throw New Exception("Message")aby nasz kod celowo łamał:

    If SomethingReallyBad = True Then
        Throw New Exception("Something Really Bad happened and we cannot continue.")
    End If

W VS2015, kiedy mówimy, wyrzucany jest klasyczny „System.Exception” Throw New Exception. Dlatego musieliśmy zaznaczyć opcję „System.Exception” w nowych ustawieniach wyjątków:

Sprawdź System.Exception Box

Po sprawdzeniu nasz kod działał zgodnie z oczekiwaniami.

J.Wyckoff
źródło
1

Rozwiązanie jest takie, że semantycznie jest to przeciwieństwo tego, co myślisz, że ustawiasz. Musisz upewnić się, że Kontynuuj, gdy nieobsługiwane w kodzie użytkownika nie jest włączone, tj. Nie jest zaznaczone, jak pokazano w kolumnie Dodatkowe działania w zakładce Ustawienia wyjątków - patrz poniżej:

efektywnie mówisz nie kontynuuj (tj. przerywaj), gdy nie jest obsługiwany w kodzie

Okno Ustawienia wyjątków (Control + Alt + E)

Aby to zrobić:

  1. Kliknij prawym przyciskiem myszy wyjątek lub zestaw wyjątków, na których Ci zależy (tj. Zwykle górny wiersz „Wyjątki środowiska uruchomieniowego języka wspólnego” w drzewie)
  2. Wybierz opcję Kontynuuj po nieobsługiwaniu w kodzie użytkownika (patrz poniżej)
  3. Upewnij się, że wyjątki niezaznaczone (patrz poniżej)
  4. kontynuuj debugowanie

wprowadź opis obrazu tutaj

Zrobiło to dla mnie - znowu szczęśliwy.

To było w VS 2015

Simon Sanderson
źródło
0

Zdecydowanie jest jakiś błąd w programie Visual Studio, który może spowodować zablokowanie go wymagającego ponownego uruchomienia. Nawet VS2015.

Miałem sytuację z pojedynczym wątkiem, w której NullReferenceExceptionzostał złapany przez „zewnętrzny” program obsługi (nadal w moim kodzie), mimo że poprosiłem o jego zerwanie, gdy został podniesiony.

Zdaję sobie sprawę, że jest to wyjątek „obsłużony” i mówisz o „nieobsłużonym” - jednak jestem prawie pewien, że czasami szybkie ponowne uruchomienie VS to naprawi, jeśli IISRESET tego nie zrobi.

Simon_Weaver
źródło
0

Program Visual Studio 2017 działa dobrze z obsługą błędów. Z drugiej strony program Visual Studio 2015 jest do bani w obsłudze błędów w zadaniach, ponieważ w trybie debugowania wszystkie wyjątki występujące w zadaniu asynchronicznym są przechwytywane, ale jeśli przekroczę je, po prostu zawiesza się na czas nieokreślony. Jeśli zostanie wykonany bez debugowania, zawiesza się na czas nieokreślony bez złapania żadnego wyjątku !!! Uwielbiam Visual Studio i używam go od 1995 i 2015 jest zdecydowanie gorszą wersją, chociaż przeskoczyłem bezpośrednio z 2010 do 2015. Spędziłem 8 godzin próbując uzyskać obsługę wyjątku, pracując bez powodzenia. Skopiowałem dokładny kod do 2017 roku na moim domowym komputerze i działał idealnie. Jestem bardzo zirytowany, że Microsoft wepchnął zadania do frameworka, którego kompilator 2015 nie może poprawnie obsłużyć.

Mojżesz
źródło