web-dev-qa-db-fra.com

Si (false == true) exécute un bloc quand une exception est lancée à l'intérieur

J'ai un problème assez étrange qui se passe.

Ceci est mon code:

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

Cela semble très simple, cela ne devrait pas toucher le Console.WriteLine ou le throw. Pour une raison quelconque, il frappe toujours le throw.

Si je déplace le throw dans sa propre méthode, alors cela fonctionne bien. Ma question est: comment ignore-t-il le bloc if et frappe-t-il le throw new Exception:

Here is some evidence

EDIT 1: J'ai mis à jour mon code pour inclure la signature, j'ai supprimé tout ce qui n'était pas lié à ce problème et je l'ai exécuté, cela se produit toujours.

151
George

Il semble que ce soit le bogue de la méthode async, le code n'est pas réellement exécuté, mais le débogueur avance à la ligne avec throw déclaration. S'il y a des lignes de code avant l'instruction throw à l'intérieur de if ces lignes sont ignorées, le débogueur ne se charge que du ligne avec l'instruction throw.

De plus, si vous n'utilisez pas la variable - if (false) ou if (true == false), le débogueur passe à la ligne de code correcte - à l'accolade fermante.

Ce bogue a été publié par @ Matthew Watson pour l’équipe de Visual Studio (lien non disponible pour le moment).

Voir aussi une question similaire - Vérification de la condition dans la méthode asynchrone

EDIT (2017/10/06):

Le problème ne peut pas être reproduit dans VS 2017 15.3.5 à l'aide de .Net Framework 4.7. On dirait que l'équipe de VS a résolu ce problème.

175
Roman Doskoch

Juste un addendum à la réponse, j'ai récemment rencontré le même problème et j'ai examiné le code x86 dans le débogueur. Il a été généré de manière étrange comme ceci (simplifié):

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

Ainsi, au lieu de sauter directement aux dernières instructions de la méthode, il effectue un double saut, où je crois que le deuxième saut inconditionnel est reconnu à tort comme faisant partie du code contenu dans le bloc if.

Je suppose donc que ce bogue pourrait être lié au compilateur JIT.

8
Serge Semenov