ThreadAbortException. I’m just fine, but thank you for asking.

I found a fun one today. I was working on an page that was having some funny behavior. When you clicked the Search button, instead of being redirected to a search results page, it was going to an error page. I dug into the code and there was not really anything wrong. So, why did I get the error page instead of the results page.

First, a little background: In, I’ve always known that a Response.Redirect throws a System.Threading.ThreadAbortException. Whenever I make a web app, and put some air-tight logging mechanisms in it, these show up in my error logs. Even when everything is going as planned, Redirect() seems to cause an Exception to be thrown.

This is one of those weird examples of why .NET has “Exception”s instead of “Error”s. There is a difference sometimes.   This is one of those times.

The reason this gets thrown is because it is your last chance to do something on a thread that is being aborted. Let’s just say, for example that maybe, just maybe, you might have been using an object that needs to be closed/disposed, etc. and it was not in a “Using” block. For instance, what if you had a COM object, like an office automation object or a custom DLL that makes calls to a USB/Com1 port to communicate with some homemade hardware (for instance).   Well, of course you are awesome and you already know that this should be in a “Using” block. But let’s just say that maybe you work with some rookies and they are not always attentive. Maybe they make mistakes and you would prefer to not give them an opportunity to make a mistake that will hang your web server. The next time that one of those well-meaning rookies plops a Response.Redirect() right in the middle of nowhere, you will be lucky, because you had a Try/Catch block and you caught the thread abort (just in case) and did a Dispose(), if you still needed to.

So, in other words, the System.Threading.ThreadAbortException is like a “last call” for Dispose() or some other clean-up code. There are probably nicer ways to handle it, but if you don’t want to take that chance, this little gem will catch your leaks.

Most of the time (nearly all of the time) you don’t need this and you don’t need to care. You could just ignore it, but the perfectionist in me wants to fix them. After all, they are exceptions. Exceptions are bad. …Must…fix…

So, if you are like me, and you want perfection in your error logs, here is what you do:

   //This would probably be a bunch of wicked-cool source code that might 
   // (or might not) use COM or custom DLLs or unmanaged code. Regardless, 
   // it is still very cool, but not dangerous to the server in any way, 
   // or likely to leak any resources, etc. because we are going to catch 
   // the exception, below.
catch (System.Threading.ThreadAbortException tae)
   //Always include a comment that shows that you intentionally chose 
   // to ignore this exception. Otherwise, someone might be under the 
   // mistaken impression that you are a numbskull who periodically creates 
   // empty catch blocks.
//You could have another catch right here, that does a re-throw or some 
// other logging. Remember that the catch (above) ONLY catches the 
// ThreadAbortException. All other exceptions are ignored.

Now your ultra error handler logs will not get crammed full of trivial non-errors.


About Tim Golisch

I'm a geek. I do geeky things.
This entry was posted in .net, CodeProject, Errors, Programming. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s