Ignore ThreadAbortException when logging exceptions
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 );
}
精彩评论