Este é um problema curioso.
O código que você postou deve trabalhar. Parece que há algum tipo de otimização acontecendo que decide não chamar seu manipulador catch.
Então, eu queria para detectar a exceção com o seguinte:
bool threadAborted = true;
try {
try { }
finally { /* critical code */ }
threadAborted = false;
}
finally {
Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");
(Meu código atual apenas dormia em que seção de código crítico, para que eu pudesse ter certeza de que iria abortar depois que finalmente.)
É impressa:
Tópico abortada? Falso
Hmmm, realmente estranho!
Então eu pensei em fazer um pouco mais de trabalho lá, para enganar qualquer otimizações "inteligentes":
bool threadAborted = true;
try {
try { }
finally { /* critical code */ }
threadAborted = AmIEvil();
}
finally {
Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");
Onde AmIEvil
é apenas:
[MethodImpl(MethodImplOptions.NoInlining)]
static bool AmIEvil() {
return false;
}
Finalmente, impressos:
Tópico abortada? Verdade
E aí está. Usar isso em seu código:
try {
try { }
finally { /* critical code */ }
NoOp();
}
catch (Exception ex) {
// ThreadAbortException is caught here now!
}
Onde NoOp
é apenas:
[MethodImpl(MethodImplOptions.NoInlining)]
static void NoOp() { }