2014-01-10 69 views
7

在asp.net中執行Response.End();方法時拋出了我在catch塊中處理的ThreadAbortException。內部catch塊結束後,我想執行一些進一步的代碼,但它直接跳到外部catch塊。這是因爲響應已經結束,.NET框架不執行任何進一步的代碼?執行Response.End()方法時在asp.net中處理ThreadAbortException異常

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

應該在「下載樣品後進行進一步處理」中做了什麼?該頁面將完成其任務(爲下載文件提供服務,您希望下一步做什麼? – Alexander

+0

@Alexander:我只發佈了我創建的sampel代碼來解釋我的場景,真正的代碼在加載之前做了很多事情,下載currentaly後,我已經做了我們的下載代碼之後,我想糾正和移出catch塊的catch塊。 –

+0

我認爲,儘管如此,但我問的原因是,我害怕你使用的頁面生命週期錯誤,因此,對我來說這是一個重要的問題,對於Page,在結束迴應之後,生活就結束了 – Alexander

回答

6

而不是

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; 
    } 
} 
+0

你的解決方案也在工作,但「Sample.txt」文件內容正在使用頁面apsx內容進行編輯 –

+1

一些額外的內容會自動添加到我的Sample.txt文件中,並且這種conded看起來像頁面aspx代碼。我的Sample.txt文件只有「Name ######## ID ######## DateDone」,但下載後它包含「Name ######## ID ###### ## DateDone「<!DOCTYPE html PUBLIC」 - // W3C // DTD XHTML 1.0 Transitional // EN「」w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd「>; ; ......。 。 .... - –

+0

嗨,你需要有內容長度的addheader。我已更新解決方案。請檢查一下。我也有同樣的問題。請在這裏參考stackoverflow.com/questions/20605705/getting-unwanted-output-when-using-response-binarywritemybyte-and-context-appl –

2

這是因爲您不會在您的catch塊中調用Thread.ResetAbort。沒有它,CLR將不會繼續執行這種方法。所以你的代碼應該是:

try 
{ 
    ... 
} 
catch (System.Threading.ThreadAbortException abrtEx) 
{ 
    Thread.ResetAbort(); 
} 

但這不是一個好習慣。你可以閱讀爲什麼它是有害的:在這裏 - Is Response.End() considered harmful?

就可以完成你的邏輯,然後經過它到Response.End調用(),而不是方法的中間

+0

它的工作,但「Sample.txt」文件內容gett ing編輯頁面apsx內容 –

+0

爲什麼你的意思是'文件內容編輯'? –

+0

一些額外的內容會自動添加到我的Sample.txt文件中,而這個conded看起來像頁面aspx代碼。我的Sample.txt文件只有「Name ######## ID ######## DateDone」,但下載後它包含「Name ######## ID ###### ## DateDone「 <!DOCTYPE html PUBLIC」 - // W3C // DTD XHTML 1.0 Transitional // EN「」http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd「> .....。 。 .... –

4

根據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(字符串 URL,布爾endResponse)該通行證的endResponse 參數來抑制內部呼叫到到Response.End假。例如: 例如:Response.Redirect(「nextpage.aspx」,false); 如果使用此替代方法,將執行Response.Redirect的代碼。

對於Server.Transfer的,使用使用Server.Execute方法來代替。

此行爲是設計使然。