Ceci est un problème curieux.Le code que vous avez publié doit. Il semble qu'il y ait une sorte d'optimisation qui décide de ne pas appeler votre gestionnaire de prises.
Donc, je voulais détecter l'exception avec ceci:
bool threadAborted = true;
try {
try { }
finally { /* critical code */ }
threadAborted = false;
}
finally {
Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");
(. Mon code actuel juste dormi dans cette section de code critique, pour que je puisse être sûr qu'il serait abandonner après enfin)
Il a imprimé:
Fil annulé? Faux
Hmmm, étrange en effet!
Je pensais à faire un peu plus de travail là-bas, pour tromper les optimisations "intelligentes":
bool threadAborted = true;
try {
try { }
finally { /* critical code */ }
threadAborted = AmIEvil();
}
finally {
Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");
Où AmIEvil
est juste:
[MethodImpl(MethodImplOptions.NoInlining)]
static bool AmIEvil() {
return false;
}
Enfin, il imprimé:
Fil annulé? Vrai
Et voilà. Utilisez dans votre code:
try {
try { }
finally { /* critical code */ }
NoOp();
}
catch (Exception ex) {
// ThreadAbortException is caught here now!
}
Où NoOp
est juste:
[MethodImpl(MethodImplOptions.NoInlining)]
static void NoOp() { }
Le finalement n'est pas ignoré. Le 'ThreadAbortException' attendait d'être jeté jusqu'à _after_ le' catch' car le 'try' était dans une CER (Contrained Execution Region). L'appel de méthode le rend tel qu'il ne peut pas être un CER. –