Jeśli (false == true) wykonuje blok, gdy zgłoszenie wyjątku jest wewnątrz


152

Mam dość dziwny problem, który się pojawia.

To jest mój kod:

private async Task BreakExpectedLogic()
{
    bool test = false;
    if (test == true)
    {
        Console.WriteLine("Hello!");
        throw new Exception("BAD HASH!");
    }
}

Wydaje się bardzo proste, nie powinno trafiać Console.WriteLineani w throw. Z jakiegoś powodu zawsze uderza w throw.

Jeśli przestawię się throwna własną metodę, to działa dobrze. Moje pytanie brzmi: jak to jest ignorować ifblok i trafiać w throw new Exception:

Oto kilka dowodów

EDYCJA 1: Zaktualizowałem kod, aby zawierał podpis, usunąłem wszystko, co nie jest związane z tym problemem i uruchomiłem go, nadal się dzieje.


5
@TimSchmelter, obraz czy to debugowanie, żółte wyróżnienie to miejsce, w którym znajduje się kod
George

5
Właśnie stworzyłem aplikację konsolową z pustym rdzeniem Main, wkleiłem tylko twój kod do i ... niespodzianka, norepro. Albo się mylisz, albo przegapiłeś jakiś ważny szczegół.
Jamiec

16
Czy to przypadkiem asyncmetoda? Ponieważ wydaje się podobny do stackoverflow.com/questions/42528458/ ...
Matthew Watson

7
@George: nadal nie ma dowodów, ponieważ możesz użyć starych symboli debugowania. Ponownie skompiluj w trybie debugowania, a następnie uruchom ponownie.
Tim Schmelter,

4
@TimSchmelter Ponownie skompilowałem, wyczyściłem, ponownie otworzyłem projekt. Wypróbowałem różne sposoby zrobienia „if”, ale wciąż to samo
George

Odpowiedzi:


176

Wydaje się, że jest to błąd w asyncmetodzie, kod nie jest faktycznie wykonywany, ale debugger przechodzi do linii z throwinstrukcją. Jeśli istnieje kilka wierszy kodu przed throwinstrukcją wewnątrz iftych linii, które są ignorowane, debugger przechodzi tylko do linii z throwinstrukcją.

Ponadto, jeśli nie używasz zmiennej - if (false)lub if (true == false)debugera kroków do prawidłowego wiersza kodu - do zamykającego nawiasu klamrowego.

Ten błąd został opublikowany przez @Matthew Watsona w zespole programu Visual Studio (łącze nie jest teraz dostępne).

Zobacz też podobne pytanie - Sprawdzanie stanu w metodzie asynchronicznej

EDYCJA (06.10.2017):

Nie można odtworzyć problemu w VS 2017 15.3.5 przy użyciu .Net Framework 4.7. Wygląda na to, że zespół VS rozwiązał ten problem.


20
Dziękuję, nie wiedząc, że to błąd w debugerze, prawdopodobnie zwariowałbym.
George,

121
Błąd w debugerze? Jak bardzo meta. :) (śpiewając nigdy wcześniej nie spotkałem takiego błędu ... )
Simba

3
@George Mam nadzieję, że nie masz nic przeciwko, pobrałem twoją próbkę i utworzyłem aplikację konsolową, używając jej, i dołączyłem ją do numeru VS, do którego odsyłał Roma.
Obsidian Phoenix

5
@Simba: Powiedz mi, że nigdy nie używałeś debugera do debugowania samego siebie.
Joshua

3
Hmm. Wygląda na to, że błąd może znajdować się w informacjach debugowania generowanych przez kompilator, a nie w samym debugerze. Poczekam, aż MS potwierdzi błąd Connect przed głosowaniem w górę lub w dół.
Adrian McCarthy

10

To tylko dodatek do odpowiedzi, ostatnio napotkałem ten sam problem i spojrzałem na rzeczywisty kod x86 w debugerze i został on wygenerowany w dziwny sposób, taki jak ten (uproszczony):

// if (...) {
0001: jne 0006
...
0006: jmp 0007
// }
0007: ret

Więc zamiast bezpośrednio przeskakiwać do ostatniej instrukcji metody, wykonuje podwójny skok, w którym moim zdaniem drugi bezwarunkowy skok jest błędnie rozpoznawany jako część kodu wewnątrz ifbloku.

Więc spekuluję, że ten błąd może być związany z kompilatorem JIT.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.