[c#] How to Avoid Response.End() "Thread was being aborted" Exception during the Excel file download

I tried to convert my dataset into excel and download that excel .I got my required excel file.But System.Threading.ThreadAbortException was raised every excel download. How to resolve this issue ?.. Please help me...

I call this method in my aspx screen.There also same exception has thrown by this method.

I call that public void ExportDataSet(DataSet ds) function in many aspx screens and also I am maintaining error logger method for exceptions which are raised at runtime right those exceptions are write into a .txt files. So that same exception is logged in all the aspx screen's txt files.I just want to avoid this exception throws from method declared class file to aspx. Simply i just want to handle this exception at my method declaration class file itself.

ASPX File Method call: excel.ExportDataSet(dsExcel);

Method Definition:

public void ExportDataSet(DataSet ds)
{

   try
   {
      string filename = "ExcelFile.xls";
      HttpResponse response = HttpContext.Current.Response;
      response.Clear();
      response.Charset = "";
      response.ContentType = "application/vnd.ms-excel";
      response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
      using (StringWriter sw = new StringWriter())
      {
         using (HtmlTextWriter htw = new HtmlTextWriter(sw))
         {
             GridView dg = new GridView();
             dg.DataSource = ds.Tables[0];
             dg.DataBind();
             dg.RenderControl(htw);
             // response.Write(style);
             response.Write(sw.ToString());                                                
             response.End();                    // Exception was Raised at here
         }
      }
   }
   catch (Exception ex)
   {
      string Err = ex.Message.ToString();
      EsHelper.EsADLogger("HOQCMgmt.aspx ibtnExcelAll_Click()", ex.Message.ToString());
   }
   finally
   {                
   }
}

This question is related to c# asp.net

The answer is


the error for Response.END(); is because you are using a asp update panel or any control that using javascript, try to use control native from asp or html without javascript or scriptmanager or scripting and try again


Use a special catch block for the exception of the Response.End() method

{
    ...
    context.Response.End(); //always throws an exception

}
catch (ThreadAbortException e)
{
    //this is special for the Response.end exception
}
catch (Exception e)
{
     context.Response.ContentType = "text/plain";
     context.Response.Write(e.Message);
}

Or just remove the Response.End() if your building a filehandler


I used all above changes but still I was getting same issue on my web application.

Then I contacted my hosting provide & asked them to check if any software or antivirus blocking our files to transfer via HTTP. or ISP/network is not allowing file to transfer.

They checked server settings & bypass the "Data Center Shared Firewall" for my server & now our application is able to download the file.

Hope this answer will help someone.This is what worked for me


This helped me to handle Thread was being aborted exception,

try
{
   //Write HTTP output
    HttpContext.Current.Response.Write(Data);
}  
catch (Exception exc) {}
finally {
   try 
    {
      //stop processing the script and return the current result
      HttpContext.Current.Response.End();
     } 
   catch (Exception ex) {} 
   finally {
        //Sends the response buffer
        HttpContext.Current.Response.Flush();
        // Prevents any other content from being sent to the browser
        HttpContext.Current.Response.SuppressContent = true;
        //Directs the thread to finish, bypassing additional processing
        HttpContext.Current.ApplicationInstance.CompleteRequest();
        //Suspends the current thread
        Thread.Sleep(1);
     }
   }

if you use the following the following code instead of HttpContext.Current.Response.End() , you will get Server cannot append header after HTTP headers have been sent exception.

            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.SuppressContent = True;
            HttpContext.Current.ApplicationInstance.CompleteRequest();

Hope it helps


Looks to be the same question as:

When an ASP.NET System.Web.HttpResponse.End() is called, the current thread is aborted?

So it's by design. You need to add a catch for that exception and gracefully "ignore" it.


I recommend this solution :

  1. Don't use response.End();

  2. Declare this global var : bool isFileDownLoad;

  3. Just after your (response.Write(sw.ToString());) set ==> isFileDownLoad = true;

  4. Override your Render like :

    /// AEG : Very important to handle the thread aborted exception
    
    override protected void Render(HtmlTextWriter w)
    {
         if (!isFileDownLoad) base.Render(w);
    } 
    

flush the response to the client before response.end()

More about Response.Flush Method

So use the below-mentioned code before response.End();

response.Flush();  

I researched online and saw that the Response.End() always throws an exception.

Replace this: HttpContext.Current.Response.End();

With this:

HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.

Move the Response.End() to outside of the Try/Catch and Using blocks.

It's suppose to throw an Exception to bypass the rest of the request, you just weren't suppose to catch it.

bool endRequest = false;

try
{
    .. do stuff
    endRequest = true;
}
catch {}

if (endRequest)
    Resonse.End();

I removed the linkbutton from the UpdatePanel and also commented the Response.End() Success!!!


For me only works

HttpContext.Current.ApplicationInstance.CompleteRequest().

https://stackoverflow.com/a/21043051/1828356


This is not issue but this is by design. The root cause is described in Microsoft Support Page.

The Response.End method ends the page execution and shifts the execution to the Application_EndRequest event in the application's event pipeline. The line of code that follows Response.End is not executed.

The provided Solution is:

For Response.End, call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event

Here is the link: https://support.microsoft.com/en-us/help/312629/prb-threadabortexception-occurs-if-you-use-response-end--response-redi


I know, this is an old question, but couldn't find the solution here. After some tries, I found out, that some added "<asp:UpdatePanel" had been the reason.

After (re)moving them, all works fine like before.


I found that the following worked better...

   private void EndResponse()
    {
        try
        {
            Context.Response.End();
        }
        catch (System.Threading.ThreadAbortException err)
        {
            System.Threading.Thread.ResetAbort();
        }
        catch (Exception err)
        {
        }
    }

I found the reason. If you remove update panels it woks fine!


Just put the

Response.End();

within a finally block instead of within the try block.

This has worked for me!!!.

I had the following problematic (with the Exception) code structure

...
Response.Clear();
...
...
try{
 if (something){
   Reponse.Write(...);
   Response.End();

   return;

 } 

 some_more_code...

 Reponse.Write(...);
 Response.End();

}
catch(Exception){
}
finally{}

and it throws the exception. I suspect the Exception is thrown where there is code / work to execute after response.End(); . In my case the extra code was just the return itself.

When I just moved the response.End(); to the finally block (and left the return in its place - which causes skipping the rest of code in the try block and jumping to the finally block (not just exiting the containing function) ) the Exception ceased to take place.

The following works OK:

...
Response.Clear();
...
...
try{
 if (something){
   Reponse.Write(...);

   return;

 } 

 some_more_code...

 Reponse.Write(...);

}
catch(Exception){
}
finally{
    Response.End();
}

For me it helped to register a button that calls code behind code as a postback control.

protected void Page_Init(object sender, EventArgs e)
{
    ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(btnMyExport);
}