[英]ThreadAbortException handling in asp.net while executing Response.End() method
執行Response.End();
在asp.net中的方法拋出我在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;
}
}
代替
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;
}
}
根據PRB:如果您使用Response.End,Response.Redirect或Server.Transfer,則會發生ThreadAbortException :
如果使用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方法。
此行為是設計使然。
這是因為您不在catch塊中調用Thread.ResetAbort 。 沒有它,CLR將不會繼續執行此方法。 所以你的代碼應該是:
try
{
...
}
catch (System.Threading.ThreadAbortException abrtEx)
{
Thread.ResetAbort();
}
但這不是一個好習慣。 你可以在這里閱讀為什么它有害 - Response.End()被認為是有害的嗎?
您可以完成邏輯,然后調用Response.End(),而不是在方法的中間
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.