执行Response.End()方法时在asp.net中处理ThreadAbortException

时间:2014-01-10 11:16:04

标签: c# asp.net .net

在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;
    }


}

3 个答案:

答案 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(),而不是在方法的中间