24

In the code below, sometimes someFunctionCall() generates an exception:

Thread was being aborted.

How come the code in code Block B never runs? Does ASP.NET start a new thread for each method call? I was suprised to see that when this exception happens the code in Block B never runs, the method returns, and my application keeps running. Can someone please explain this?

public void method()
{
     // CODE BLOCK A
     //...    

     try 
     {
         someFunctionCall(); // this call is generating thread abort exception
     }
     catch(Exception ex)
     {
         // log exception message
     }

    // CODE BLOCK B
    // ...    
}
Dale K
  • 25,246
  • 15
  • 42
  • 71
Ryan Sampson
  • 6,717
  • 12
  • 47
  • 55

4 Answers4

37

This is a ThreadAbortException; it's a special exception that is automatically rethrown at the end of every catch block, unless you call Thread.ResetAbort().

ASP .Net methods like Response.End or Response.Redirect (unless you pass false) throw this exception to end processing of the current page; your someFunctionCall() is probably calling one of those methods.

ASP .Net itself handles this exception and calls ResetAbort to continue processing.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
3

To work around this problem, use one of the following methods: For Response.End, call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event.

For Response.Redirect, use an overload, Response.Redirect(String url, bool endResponse) that passes false for the endResponse parameter to suppress the internal call to Response.End. For example:

Response.Redirect ("nextpage.aspx", false);

If you use this workaround, the code that follows Response.Redirect is executed. For Server.Transfer, use the Server.Execute method instead.

Sujeet Sinha
  • 2,417
  • 2
  • 18
  • 27
1

What worked for me is increasing the "Idle Time-out (minutes)" property for the Application Pool on IIS.

I set it to "43200" which is the max value.

I also adjusted the recycling settings ...

Adel Mourad
  • 1,351
  • 16
  • 13
-2

Try this way :

This is my extension method :

 public static void WriteJSONObject(this HttpResponse response, object content) {
            response.ContentType = "application/json";
            response.Write(new JavaScriptSerializer().Serialize(content));
            response.End();

 }

And the logic :

public void RegisterUser() {
    try {
        Response.WriteJSONObject(new { Result = "See hello" });
    } 
    catch (Exception err) {
        if (err.Message != "Thread was being aborted.")
            Response.WriteJSONObject(new { Result = err.Message });
        else {
            Response.End();
        }
    }
}
Tarik
  • 79,711
  • 83
  • 236
  • 349
  • 14
    This is wrong. You should _never_ compare an exception's `Message` to a hard-coded string. Instead, you can write `catch (ThreadAbortException) {} catch (Exception ex) { ... }`. Also, there's no point in calling `Response.End` if there's already a `ThreadAbortException`. – SLaks Dec 25 '09 at 13:57
  • P.s : The solutions above didn't work for me like most people. No matter what I did didn't work so this is the only solution I've found and works just fine. – Tarik Dec 25 '09 at 17:29
  • 6
    I wasn't saying that it won't work; I'm saying that it's a horrible idea. Your code is solving a different problem that has nothing to do with this question. – SLaks Dec 25 '09 at 19:25