Se (false == true) executar o bloco quando a exceção de lançamento estiver dentro


152

Eu tenho um problema bastante estranho que está ocorrendo.

Este é o meu código:

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

Parece realmente simples, não deve atingir o Console.WriteLineou o throw. Por alguma razão, está sempre atingindo o throw.

Se eu mover o throwmétodo para seu próprio método, ele funcionará bem. Minha pergunta é como ele está ignorando o ifbloco e atingindo o throw new Exception:

Aqui estão algumas evidências

EDIÇÃO 1: atualizei meu código para incluir a assinatura, removi tudo que não estava relacionado a esse problema e o executei, ainda acontece.


5
@TimSchmelter a imagem está sendo depurado, o destaque amarelo é onde o código está em
— George

5
Acabei de criar um aplicativo de console central em branco, colei apenas seu código no Maine .... surpresa, norepro. Ou você está enganado ou perdeu alguns detalhes importantes.
— Jamiec

16
Isso está em um asyncmétodo por acaso? Porque parece semelhante a stackoverflow.com/questions/42528458/…
— Matthew Watson

7
@ George: ainda não há evidências, porque você pode usar símbolos de depuração antigos. Recompile no modo de depuração e inicie novamente.
— Tim Schmelter

4
@TimSchmelter eu recompilados, limpo, reabriu o projecto tentou maneiras diferentes de fazer o caso, mas ainda o mesmo
— George

Respostas:


176

Parece ser o erro no asyncmétodo, o código não é realmente executado, mas o depurador avança para a linha com a throwinstrução Se houver algumas linhas de código antes que a throwinstrução dentro ifdessas linhas seja ignorada, o depurador passará apenas para a linha comthrow instrução

Além disso, se você não usar variável - if (false)ouif (true == false) etapas do depurador para a linha de código correta - para a chave de fechamento.

Este bug foi publicado por @Matthew Watson na equipe do Visual Studio (o link não está disponível agora).

Consulte também perguntas semelhantes - Verificação de condição no método assíncrono

EDIT (06/10/2017):

O problema não pode ser reproduzido no VS 2017 15.3.5 usando o .Net Framework 4.7. Parece que a equipe do VS corrigiu esse problema.


20
Obrigado, sem saber que isso é um bug no depurador, eu provavelmente ficaria louco.
— George

121
Um bug no depurador? Que meta! :) (cantando Eu nunca meta bug como isso antes ... )
— Simba

3
@ George Espero que você não se importe, eu peguei sua amostra e criei um aplicativo de console usando-o e anexei-o ao problema do VS ao qual Roma se vinculou.
— Obsidian Phoenix

5
@ Simba: Diga-me que você nunca usou um depurador para depurar a si próprio.
— Joshua

3
Hmm. Parece que o erro pode estar nas informações de depuração geradas pelo compilador, e não no próprio depurador. Esperarei que a Microsoft reconheça o bug do Connect antes de votar para cima ou para baixo.
— Adrian McCarthy

10

Apenas um adendo à resposta, encontrei recentemente o mesmo problema e olhei o código x86 real no depurador, e ele foi gerado de uma maneira estranha como esta (simplificada):

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

Então, em vez de pular diretamente para as últimas instruções do método, ele dá um pulo duplo, onde acredito que o segundo pulo incondicional é erroneamente reconhecido como parte do código interno if bloco.

Então, eu especularia que esse bug possa estar relacionado ao compilador JIT.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.