2014-01-10 31 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方法来代替。

此行为是设计使然。