在asp.net中执行Response.End();
方法时,抛出我在catch块中处理的ThreadAbortException
,在内部catch块结束后我想执行一些其他代码,但它直接跳转到外部catch块。这是因为响应已经结束而且.net框架不执行任何进一步的代码吗?
protected void btn_click(object sender, EventArgs e)
{
try
{
string fileToDownload = MapPath(@"~\Sample.txt");
string fileToRead = MapPath(@"~\FileNotExist.txt");
try
{
//Section 1
try
{
// try to read the file which does not exist to raise the exception
StreamReader ss = new StreamReader(fileToRead);
}
catch (IOException IoEx)
{
// Just for sample exception
}
// Section 2 code block still execute because exception handled by upper try catch block
//Section 2
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "attachment;filename=SampleTemplate.txt");
Response.ContentType = "text";
Response.WriteFile(fileToDownload);
Response.Flush();
Response.End();
}
catch (System.Threading.ThreadAbortException abrtEx)
{
// do not treat this exception as Exception
}
//Section 3 Code block not executing even after exception handeled by ThreadAbortException
//Section 3
string test = "Do futher process after sample downloaded";
}
catch (Exception ex) // Outer Catch Block
{
throw ex;
}
}
答案 0 :(得分:7)
而不是
Response.End()
使用
HttpContext.Current.ApplicationInstance.CompleteRequest()
喜欢这个
protected void btn_click(object sender, EventArgs e)
{
try
{
string fileToDownload = MapPath(@"~\Sample.txt");
string fileToRead = MapPath(@"~\FileNotExist.txt");
try
{
//Section 1
try
{
// try to read the file which does not exist to raise the exception
StreamReader ss = new StreamReader(fileToRead);
}
catch (IOException IoEx)
{
// Just for sample exception
}
// Section 2 code block still execute because exception handled by upper try catch block
//Section 2
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Length", fileToDownload.Length.ToString());
Response.AddHeader("Content-Disposition","attachment;filename=SampleTemplate.txt");
Response.ContentType = "text";
Response.WriteFile(fileToDownload);
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch (System.Threading.ThreadAbortException abrtEx)
{
}
//Section 3 Code block not executing even after exception handeled by ThreadAbortException
//Section 3
string test = "Do futher process after sample downloaded";
}
catch (Exception ex) // Outer Catch Block
{
throw ex;
}
}
答案 1 :(得分:5)
根据PRB: ThreadAbortException Occurs If You Use Response.End, Response.Redirect, or Server.Transfer:
如果您使用 Response.End , Response.Redirect ,或者 Server.Transfer 方法,发生 ThreadAbortException 异常。您可以使用try-catch语句来捕获此异常。
Response.End 方法结束页面执行并转移 执行到应用程序中的 Application_EndRequest 事件 事件管道。 Response.End 后面的代码行不是 执行。
Response.Redirect 和中出现此问题 Server.Transfer 方法,因为两个方法都在内部调用Response.End。
解决此问题
,使用以下方法之一:
对于 Response.End ,请致电 HttpContext.Current.ApplicationInstance.CompleteRequest 方法而不是 Response.End 绕过代码执行到 Application_EndRequest 事件。
对于 Response.Redirect ,请使用重载 Response.Redirect(String url,bool endResponse)为endResponse传递false 用于禁止内部调用 Response.End 的参数。对于 示例: Response.Redirect(" nextpage.aspx",false); 如果使用此解决方法,则会执行 Response.Redirect 后面的代码。
对于 Server.Transfer ,请改用 Server.Execute 方法。
此行为是设计使然。
答案 2 :(得分:3)
这是因为你没有在catch块中调用Thread.ResetAbort。没有它,CLR将不会继续执行此方法。所以你的代码应该是:
try
{
...
}
catch (System.Threading.ThreadAbortException abrtEx)
{
Thread.ResetAbort();
}
但这不是一个好习惯。你可以在这里阅读它有害的原因 - Is Response.End() considered harmful?
你可以完成你的逻辑,然后调用Response.End(),而不是在方法的中间