How can I detect a ThreadAbortException in a finally block? (.NET)

前端 未结 7 2184
太阳男子
太阳男子 2020-12-15 12:08

I have some critical logic in a finally block (with an empty try block), because I want to guarantee that the code gets executed even if the thread is aborted. However, I\'d

7条回答
  •  不知归路
    2020-12-15 12:28

    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() { }
    

提交回复
热议问题