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.

C’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 la 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 blocage if et frappe-t-il la throw new Exception

Voici quelques preuves

EDIT 1 J’ai mis à jour mon code pour inclure la signature, j’ai supprimé tout ce qui n’est pas lié à ce problème et je l’ai exécuté, cela arrive encore

Cela semble être le bogue de la méthode async , le code n’est pas réellement exécuté, mais le débogueur avance à la ligne avec une instruction throw . S’il y a quelques lignes de code avant l’instruction throw à l’intérieur, if ces lignes sont ignorées, le débogueur passe uniquement à la ligne avec l’instruction throw .

De même, si vous n’utilisez pas variable – if (false) ou if (true == false) le débogueur passe à la ligne de code correcte – à l’accolade fermante.

Ce problème a été signalé par @Matthew Watson à l’équipe de Visual Studio (le lien n’est pas disponible pour le moment).

Voir aussi une question similaire – Vérification de 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.

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 inside bloque.

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