DevelopingChris
DevelopingChris

Reputation: 40788

Why is my ASP.NET application throwing a ThreadAbortException?

Why does this thing bubble into my try-catches even when nothing is wrong?

Why is it showing up in my log, hundreds of times?

Upvotes: 24

Views: 13294

Answers (4)

Eric Z Beard
Eric Z Beard

Reputation: 38406

This is probably coming from a Response.Redirect call. Check the page ASP.NET - ThreadAbortException for an explanation:

Just a quick note after some discussion we had at a local user group meeting tonight with regards the ThreadAbortException you sometimes see when working with ASP.NET after making a Response.Redirect, Server.Transfer or Response.End call. Had a quick look with Reflector and on MSDN.

Calls to Response.Redirect and Server.Transfer all make calls to Response.End internally which raises a ThreadAbortException when the current response ends and execution switches to the Application_EndRequest event. The behavior is by design.

To prevent the call to Response.End use the Response.Redirect overload with the endResponse parameter set to false.

In most cases, calling Response.Redirect(url, false) fixes the problem. Be aware that adding the false overload intercepts the Response.End call, and thus any code after Response.Redirect will be executed.

Upvotes: 20

ValidfroM
ValidfroM

Reputation: 2817

The reason of why Response.Redirect will give this exception is asp.net internally implement this API with Thread.Abort(). When this method is called, a special ThreadAbortException is thrown.This exception wont be swallowed by any catch block. It will be re thrown at the end of each catch block.

Upvotes: -1

Luke Puplett
Luke Puplett

Reputation: 45105

Knowing that there are (at least) three APIs that internally use Thread.Abort, I'd like to answer in more practical terms, how to work out what to do about it.

For us, this error started being logged all-of-a-sudden. What changed? We fixed a bug in some database procedure that was dealing with sitemaps.

The log4net logs showed the X-Forwarded-For header (we're behind an NLB) was Googlebot's IP address, 66.249.78.x which bolstered my theory about the sitemap change leading to Google crawling our site more aggressively looking for images.

The first thing was to find out why only the Googlebot was able to cause this problem. No other client was triggering whatever code path uses Response.Redirect, or whatever.

So in the HttpApplication.Error handler, I added some code to log extra detailed output with all headers, and most data in the HttpResponse and HttpContext spewed to log.

This let me see that the problem was that Googlebot is using an iPhone user agent string and armed with that, I was able to search the codebase for "iPhone" and come up with:

private void CheckIPhoneAccess() { ... }

And that uses a Redirect.

What to do about it?

Well, for this aged codebase, it's not worth retro-patching all the Response.Redirect calls, so I'm going to lower the logging level for ThreadAbortException for the application.

I will change the behaviour for Googlebot's mobile crawler, that would not lead to 'lies' about what our site serves to mobiles since it only redirects on the first hit, subsequently it reads a cookie and shows the image. Googlebot does not seem to cache that cookie.

It's not perfect, but the site is due to be rebuilt. probably by another team using Scala or something, so in practical terms, I think this is a good choice. I'll add comments and may revisit the issue later, build a Response.SafeRedirect extension that encapsulates this advice:

Why Response.Redirect causes System.Threading.ThreadAbortException?

Luke

Upvotes: -1

rjzii
rjzii

Reputation: 14533

The most common reason for a ThreadAbortException is calling Response.End, Response.Redirect, or Server.Transfer. Microsoft has published some suggested functions that should be used in stead of those functions.

Upvotes: 7

Related Questions