Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何避免响应。结束();“线程正在中止”;Excel文件下载期间出现异常_C#_Asp.net - Fatal编程技术网

C# 如何避免响应。结束();“线程正在中止”;Excel文件下载期间出现异常

C# 如何避免响应。结束();“线程正在中止”;Excel文件下载期间出现异常,c#,asp.net,C#,Asp.net,我试图将数据集转换为excel并下载该excel。我获得了所需的excel文件。但每次下载excel时都会引发System.Threading.ThreadAbortException。 如何解决这个问题?。。 请帮帮我 我在我的aspx屏幕中调用了这个方法。这个方法也引发了同样的异常 我在许多aspx屏幕中调用public void ExportDataSet(DataSet ds)函数,并且我还为运行时引发的异常维护错误记录器方法,这些异常将写入.txt文件。所以相同的异常记录在所有aspx

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

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


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

ASPX文件方法调用: 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
   {                
   }
}

看起来与以下问题相同:


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

我推荐此解决方案:

  • 不要使用
    response.End()

  • 声明这个全局变量:
    boolisfiledownload

  • 就在
    (response.Write(sw.ToString());)set=>isFileDownLoad=true之后

  • 覆盖渲染,如:

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

  • 我在网上研究,发现
    Response.End()
    总是抛出异常

                HttpContext.Current.Response.Flush();
                HttpContext.Current.Response.SuppressContent = True;
                HttpContext.Current.ApplicationInstance.CompleteRequest();
    
    替换此:
    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.
    
    将Response.End()移动到Try/Catch和Using块的外部

    假设它抛出一个异常以绕过请求的其余部分,但您不应该捕获它

    bool endRequest = false;
    
    try
    {
        .. do stuff
        endRequest = true;
    }
    catch {}
    
    if (endRequest)
        Resonse.End();
    

    这有助于我处理线程被中止的异常

    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);
         }
       }
    
    如果使用以下代码而不是
    HttpContext.Current.Response.End()
    ,则会出现
    服务器无法在发送HTTP头后追加头的异常

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

    希望它有助于在响应之前将响应刷新到客户端。end()

    更多关于

    因此,在
    response.End()之前使用下面提到的代码

    把钥匙放好

    Response.End();
    
    在finally块中,而不是在try块中

    这对我很有效

    我有以下有问题的(例外)代码结构

    ...
    Response.Clear();
    ...
    ...
    try{
     if (something){
       Reponse.Write(...);
       Response.End();
    
       return;
    
     } 
    
     some_more_code...
    
     Reponse.Write(...);
     Response.End();
    
    }
    catch(Exception){
    }
    finally{}
    
    它抛出了一个异常。我怀疑在response.End()之后有代码/工作要执行时会引发异常。在我的例子中,额外的代码只是返回本身

    当我移动响应时。End();对于finally块(并将返回保留在原处-这会导致跳过try块中的其余代码并跳到finally块(而不仅仅是退出包含函数)),异常停止发生

    以下工作正常:

    ...
    Response.Clear();
    ...
    ...
    try{
     if (something){
       Reponse.Write(...);
    
       return;
    
     } 
    
     some_more_code...
    
     Reponse.Write(...);
    
    }
    catch(Exception){
    }
    finally{
        Response.End();
    }
    

    使用特殊的catch块处理Response.End()方法的异常

    {
        ...
        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);
    }
    
    或者,如果只为我构建文件处理程序,只需删除响应.End()

    HttpContext.Current.ApplicationInstance.CompleteRequest()


    Response.END()的错误;是因为您使用的是asp更新面板或任何使用javascript的控件,请尝试在不使用javascript或scriptmanager或脚本的情况下使用asp或html的本机控件,然后重试

    我从UpdatePanel中删除了linkbutton,并对响应进行了注释。End()
    成功

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

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

    提供的解决方案是:

    对于Response.End,调用HttpContext.Current.ApplicationInstance.CompleteRequest方法,而不是Response.End,以绕过对应用程序的代码执行。\u EndRequest事件

    以下是链接:

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

    然后我联系了我的主机供应商,让他们检查是否有软件或防病毒软件阻止我们的文件通过HTTP传输。或者ISP/网络不允许传输文件

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


    希望这个答案能对别人有所帮助。这就是我找到的原因。如果您删除更新面板,它就可以正常工作

    我发现以下方法效果更好

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

    对我来说,它帮助注册了一个调用代码隐藏的按钮作为回发控件

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

    我知道,这是一个老问题,但在这里找不到解决方案。
    经过一些尝试后,我发现,有些人添加了“不要使用
    响应.End
    请参见(以及其他答案);请注意,异常是“预期的”,因为它是堆栈展开的方式(因此不要捕获该异常)。如果您仍然要捕获[其他]异常,请使用:
    .catch(ThreadAbortException){throw;/*propagate*/}catch(异常示例){..}
    只是好奇一下,您使用的是什么记录器我称之为public void ExportDataSet(数据集ds)在许多aspx屏幕中运行,我还为运行时引发的异常维护错误记录器方法。这些异常会写入.txt文件。因此,相同的异常会记录在所有aspx屏幕的txt文件中。我只是想避免此异常从方法声明的类文件抛出到aspx。我只是nt在我的方法声明类文件本身处理此异常。根据用户在您的问题中的评论,只需捕获TheadAbortException-