如何避免Response.End()“线程被中止”Excel文件下载期间出现异常

时间:2014-01-08 06:27:23

标签: c# asp.net

我尝试将我的数据集转换为excel并下载excel。我得到了我所需的excel文件。但每次excel下载都会引发System.Threading.ThreadAbortException。 如何解决这个问题? 请帮帮我......

我在我的aspx屏幕中调用此方法。此方法也引发了同样的异常。

我在许多aspx屏幕中调用public void ExportDataSet(DataSet ds)函数,并且我正在为运行时引发的异常维护错误记录器方法,这些异常写入.txt文件。所以在所有aspx屏幕的txt文件中记录了相同的异常。我只想避免从方法声明的类文件抛出到aspx的异常。我只想在我的方法声明类文件中处理这个异常。

ASPX文件方法调用:  excel.ExportDataSet(dsExcel);

方法定义:

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
   {                
   }
}

16 个答案:

答案 0 :(得分:159)

我在网上研究过,看到Response.End()总是抛出异常。

替换为:HttpContext.Current.Response.End();

有了这个:

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.

答案 1 :(得分:4)

看起来与以下问题相同:

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

所以它是设计的。您需要为该异常添加一个catch并优雅地“忽略”它。

答案 2 :(得分:3)

将Response.End()移动到Try / Catch和Using块之外。

假设抛出一个Exception来绕过请求的其余部分,你只是不想抓住它。

bool endRequest = false;

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

if (endRequest)
    Resonse.End();

答案 3 :(得分:3)

Response.End()方法

外,使用特殊的catch块
{
    ...
    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);
}

如果构建文件处理程序,只需删除 Response.End()

答案 4 :(得分:2)

对我来说只有作品

  

HttpContext.Current.ApplicationInstance.CompleteRequest()。

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

答案 5 :(得分:1)

只需输入

即可
Response.End();

在最终块内,而不是在try块中。

这对我有用!!!。

我遇到了以下问题(使用Exception)代码结构

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

   return;

 } 

 some_more_code...

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

}
catch(Exception){
}
finally{}

并抛出异常。我怀疑在response.End()之后有代码/工作要执行的地方抛出Exception。 。在我的情况下,额外的代码只是返回本身。

当我刚刚移动了response.End();到finally块(并返回到它的位置 - 这导致跳过try块中的其余代码并且跳转到finally块(不仅仅是退出包含的函数))异常停止发生。

以下工作正常:

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

   return;

 } 

 some_more_code...

 Reponse.Write(...);

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

答案 6 :(得分:1)

Response.END()的错误;是因为你正在使用asp更新面板或使用javascript的任何控件,尝试使用asp或html中的控件native而不使用javascript或scriptmanager或脚本并再试一次

答案 7 :(得分:1)

我从UpdatePanel中删除了linkbutton并且还注释了Response.End() 成功!!!

答案 8 :(得分:1)

这不是问题,但这是设计上的。 Microsoft支持页中描述了根本原因。

Response.End方法结束页面执行并将执行转移到应用程序事件管道中的Application_EndRequest事件。不执行Response.End之后的代码行。

提供的解决方案是:

对于Response.End,调用HttpContext.Current.ApplicationInstance.CompleteRequest方法而不是Response.End以绕过代码执行到Application_EndRequest事件

这是链接: https://support.microsoft.com/en-us/help/312629/prb-threadabortexception-occurs-if-you-use-response-end--response-redi

答案 9 :(得分:0)

我推荐这个解决方案:

  1. 请勿使用response.End();

  2. 声明此全局变量:bool isFileDownLoad;

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

  4. 之后
  5. 覆盖您的渲染,如:

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

答案 10 :(得分:0)

在response.end()

之前刷新对客户端的响应

有关Response.Flush Method

的更多信息

所以在response.End();

之前使用下面提到的代码
response.Flush();  

答案 11 :(得分:0)

我使用了上述所有更改但仍然在我的网络应用程序中遇到了同样的问题。

然后我联系了我的托管服务&要求他们检查是否有任何软件或防病毒软件阻止我们的文件通过HTTP传输。或ISP /网络不允许文件传输。

他们检查了服务器设置&绕过我的服务器“数据中心共享防火墙”现在我们的应用程序可以下载文件。

希望这个答案对某些人有帮助。这对我有用

答案 12 :(得分:0)

我找到了原因。如果您删除更新面板,就可以正常工作!

答案 13 :(得分:0)

我发现以下方法效果更好...

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

答案 14 :(得分:0)

对我来说,它有助于注册一个按钮,该按钮将代码背后的代码称为回发控件。

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

答案 15 :(得分:0)

我知道,这是一个老问题,但在这里找不到解决方案。 经过一些尝试,我发现原因是添加了“

(重新)移动它们后,一切都像以前一样正常。