如何检测finally块中的ThreadAbortException?(.净)

Chr*_*ris 8 .net multithreading

我在finally块中有一些关键逻辑(带有空的try块),因为我想保证即使线程被中止也会执行代码.但是,我还想检测ThreadAbortException.我发现在try/catch中包装我的关键try/finally块不会捕获ThreadAbortException.有没有办法检测它?

try {
    try { }
    finally {
        // critical logic
    }
} catch(Exception ex) {
    // ThreadAbortException is not caught here, but exceptions thrown
    // from within the critical logic are
}

Jor*_*dão 8

这是一个奇怪的问题.

您发布的代码应该有效.似乎正在进行某种优化,决定不调用你的catch处理程序.

所以,我想用这个来检测异常:

bool threadAborted = true;
try {
  try { }
  finally { /* critical code */ }
  threadAborted = false;
}
finally {
  Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");
Run Code Online (Sandbox Code Playgroud)

(我的实际代码只是睡在那个关键的代码部分,所以我可以肯定它会在最终之后中止.)

它打印:

线程中止了吗?假

嗯,确实很奇怪!

所以我想在那里做更多的工作,欺骗任何"智能"优化:

bool threadAborted = true;
try {
  try { }
  finally { /* critical code */ }
  threadAborted = AmIEvil();
}
finally {
  Console.WriteLine("Thread aborted? {0}", threadAborted);
}
Console.WriteLine("Done");
Run Code Online (Sandbox Code Playgroud)

在哪里AmIEvil:

[MethodImpl(MethodImplOptions.NoInlining)]
static bool AmIEvil() {
  return false;
}
Run Code Online (Sandbox Code Playgroud)

最后打印出来:

线程中止了吗?真正

你有它.在代码中使用它:

try {
  try { }
  finally { /* critical code */ }
  NoOp();
}
catch (Exception ex) {
  // ThreadAbortException is caught here now!
}
Run Code Online (Sandbox Code Playgroud)

在哪里NoOp:

[MethodImpl(MethodImplOptions.NoInlining)]
static void NoOp() { }
Run Code Online (Sandbox Code Playgroud)