开发者

Ignore ThreadAbortException when logging exceptions

开发者 https://www.devze.com 2023-01-07 17:49 出处:网络
What\'s the correct way of ignoring ThreadAbortException when logging exceptions? Is it safe to just catch it in an empty catch block to mak开发者_如何学JAVAe it disappear?If you need to stop a Threa

What's the correct way of ignoring ThreadAbortException when logging exceptions?

Is it safe to just catch it in an empty catch block to mak开发者_如何学JAVAe it disappear?


If you need to stop a ThreadAbortException propogating further up the call stack, you can call Thread.ResetAbort. So try something like:

try
{
  // some code
}
catch (ThreadAbortException ex)
{
  // do some logging
  Thread.ResetAbort();
}

As for "correct" - that depends on your usage scenario. I'd generally be cautious about catching these unless you understand exactly why it has been raised. In escence it is a "stop now, quickly, and drop what you are doing" signal. Resetting it and going on to do further processing should be done with caution.


Employ two catch blocks: one for ThreadAbortException and one for the rest, for example:

void MainLoop()
{   bool workdone;
    try
    {   while( IsWorking ) // cross-thread volatile variable
        {   workdone = Process();
            if( !workdone )
            {   Thread.Sleep( 500 );  }
        }
    }
    catch( ThreadAbortException )
    {   // Forced termination. Exit silently.
    }
    catch (Exception e)
    {   LogError( e );  }
}


It is safe to catch it in a separate catch block. As an alternative you can catch all Exceptions and then check if a given Exception e is ThreadAbortException

I leave this post just because of the comments. Obviously, I was not knowing much about that exception.


With newer .NET versions ignoring an exception can be simplified to

try
{   // ...
}
catch (Exception e) when (!(e is ThreadAbortException))
{   LogError( e );
}

But this might still not be enough. Some libraries tend to wrap all exceptions with their own exception. In this case it could happen that the ThreadAbortExceptiononly appears as InnerException. I would not call it best practice to wrap a ThreadAbortException but it is real world.

To come around this I recommend an extension:

public static bool IsThreadAbort(this Exception ex)
{
    while (ex != null)
    {
        if (ex is ThreadAbortException)
            return true;
        ex = ex.InnerException;
    }
    return false;
}

Now you can check with:

catch (Exception e) when (!e.IsThreadAbort())
{   LogError( e );
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号