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