This is a curious problem.
The code you posted should work. It seems there's some kind of optimization going on that decides not to call your catch handler.
So, I wanted to detect the exception with this:
bool threadAborted = true;
try {
try { }
finally { /* critical code */ }
threadAborted = false;
}
finally {
Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");
(My actual code just slept in that critical code section, so I could be sure it would abort after that finally.)
It printed:
Thread aborted? False
Hmmm, strange indeed!
So I thought about doing a little bit more work there, to trick any "smart" optimizations:
bool threadAborted = true;
try {
try { }
finally { /* critical code */ }
threadAborted = AmIEvil();
}
finally {
Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");
Where AmIEvil
is just:
[MethodImpl(MethodImplOptions.NoInlining)]
static bool AmIEvil() {
return false;
}
Finally it printed:
Thread aborted? True
And there you have it. Use this in your code:
try {
try { }
finally { /* critical code */ }
NoOp();
}
catch (Exception ex) {
// ThreadAbortException is caught here now!
}
Where NoOp
is just:
[MethodImpl(MethodImplOptions.NoInlining)]
static void NoOp() { }
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…