"Exception thrown: 'System.Threading.ThreadAbortException' in mscorlib.dll" when using Response.Redirect()

Joe Schofield picture Joe Schofield · Feb 20, 2017 · Viewed 11.3k times · Source

In an OnClick method for a button in an ASP.NET web form I have a call to Response.Redirect() which causes the system to abort the thread with the error message:

Exception thrown: 'System.Threading.ThreadAbortException' in mscorlib.dll

There's a few questions similar to this on here, using their solutions I changed:

Response.Redirect("~/UI/Home.aspx");

to

Response.Redirect("~/UI/Home.aspx", false);
Context.ApplicationInstance.CompleteRequest();

However I am still getting the same problem. Using the debugger I ran through the code and it all executed successfully until I called Response.Redirect();.

OnClick Function

protected void btnLogin_Click(object sender, EventArgs e)
    {
        SiteUser s = null;
        try
        {
            string email = txtEmail.Text;
            string pwd = txtPwd.Text;
            s = DBConnection.login(email, pwd);                
        }
        catch (Exception ex)
        {
            Console.Write(ex);
            lblLoginError.Text = "Error logging in.";
        }
        if (s != null)
        {
            Session["UserSession"] = s;
            Response.Redirect("~/UI/Home.aspx", false);
            Context.ApplicationInstance.CompleteRequest();
        }
        else
        {
            lblLoginError.Text = "User not found. Please check your details and try again.";
        }
    }

Any thoughts on why this might be happening?

Answer

John Wu picture John Wu · Feb 21, 2017

I have seen this problem in the past. In theory, if you use this code, it shouldn't happen:

Response.Redirect(url, false);
Context.ApplicationInstance.CompleteRequest();

That being said, I still got these sometimes, which is really surprising. I am guessing that it sometimes occurs in the presence of an active finally block to signal the code to start cleaning itself up, although that doesn't seem to be the case for you.

The best fix I could come up with is to catch the error and ignore it.

protected void btnLogin_Click(object sender, EventArgs e)
{
    try
    {
        SiteUser s = null;
        try
        {
            string email = txtEmail.Text;
            string pwd = txtPwd.Text;
            s = DBConnection.login(email, pwd);                
        }
        catch (Exception ex)
        {
            Console.Write(ex);
            lblLoginError.Text = "Error logging in.";
        }
        if (s != null)
        {
            Session["UserSession"] = s;
            Response.Redirect("~/UI/Home.aspx", false);
            Context.ApplicationInstance.CompleteRequest();
        }
        else
        {
            lblLoginError.Text = "User not found. Please check your details and try again.";
        }
    }
    catch(System.Threading.ThreadAbortException)
    {
        //Do nothing.  The exception will get rethrown by the framework when this block terminates.
    }
}