Если (false = true) выполняется блок, когда исключение бросания находится внутри

У меня возникает довольно странная проблема.

Это мой код:

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

Кажется действительно простым, он не должен попадать в Console.WriteLine или throw. По какой-то причине это всегда бьет по throw.

Если я перемещаю throw в его собственный метод, то он работает нормально. Мой вопрос заключается в том, как игнорировать блок if и нажимать на throw new Exception:

Here is some evidence

РЕДАКТИРОВАТЬ 1: я обновил свой код, чтобы включить подпись, я удалил все, что не связано с этой проблемой и запустил его, это все еще происходит.

Ответ 1

Кажется, это ошибка в async методе, код фактически не выполняется, но отладчик переходит к строке с оператором throw. Если внутри оператора throw есть несколько строк кода, if эти строки игнорируются, отладчик переходит только к строке с оператором throw.

Кроме того, если вы не используете переменную - if (false) или if (true == false) то отладчик переходит к правильной строке кода - к закрывающей фигурной скобке.

@Matthew Watson опубликовал эту ошибку в команде Visual Studio (ссылка недоступна).

Также смотрите аналогичный вопрос - Проверка состояния в асинхронном методе

РЕДАКТИРОВАТЬ (2017/10/06):

Проблема не может быть воспроизведена в VS 2017 15.3.5 с использованием .Net Framework 4.7. Похоже, команда VS исправила эту проблему.

Ответ 2

Просто добавление к ответу, я недавно столкнулся с той же проблемой и посмотрел на фактический код x86 в отладчике, и он был сгенерирован таким странным способом, как этот (упрощенный):

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

Поэтому вместо прямого перехода к последним инструкциям метода он выполняет двойной переход, где, как я полагаю, второй безусловный переход ошибочно распознается как часть кода внутри блока if.

Поэтому я бы предположил, что эта ошибка может быть связана с компилятором JIT.