STOP using Response.Redirect(url)
OK, I made the title a little misleading to grab your attention - I'm sneaky like that. Seriously though, there are a few things about Response.Redirect(url) that every ASP .NET developer needs to know.
Using Response.Redirect() to help with site navigation is standard and all ASP .NET developers use it but, most don’t have time to stop and think about what happens under the hood. Put simply, every call to Response.Redirect(url) will throw an Exception and that’s bad…or is it?
Here is a snippet from a w3wp.exe process dump:
Exception type: System.Threading.ThreadAbortException
Message: Thread was being aborted.
InnerException: <none>
StackTrace (generated):
SP IP Function
000000000643E2F0 0000000000000001 System.Threading.Thread.AbortInternal()
000000000643E2F0 0000098278342F1A System.Threading.Thread.Abort(System.Object)
000000000643E340 00000982BC912E96 System.Web.HttpResponse.End()
This snippet shows that a call to Response.Redirect(url) asks .NET to stop processing the current web page thread and to transfer execution to another thread. Internally a call is made to Response.End() which calls Thread.Abort() which throws an exception.
Is this good, or bad, or ugly? It’s debatable so I won’t go there. All I'll say is that It would have been nice if there was some other way to notify .NET that a thread needed to be stopped besides throwing an exception but, now that the problem is understood let’s work with it and not against it.
Work with it by using Response.Redirect()’s overload that accepts a bool to determine if the request should be ended. Calling Response.Redirect(url, false) asks .NET not to abort the thread and as a result the call to Response.End() is skipped and the ThreadAbortException is avoided.
Is it that simple? Nope. There is a price to pay for not aborting the thread. All the page events and postback events will be processed, and the page will still send its HTML to the browser. Let me say that one more time, all the page events and postback events will be processed. This means any DB calls or complex calculations will still be performed.
So, what are your choices? Either program defensively by setting Boolean flags to ensure that events are not called by accident or, compromise by limiting the use of Response.Redirect, by ensuring that any call to Response.Redirect(url, false) is wrapped in an if-else block or returns immediately after the call and, most importantly, by analyzing the code to see what impact the call will have.