簡體   English   中英

執行Response.End()方法時在asp.net中處理ThreadAbortException

[英]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.EndResponse.RedirectServer.Transfer方法,則會發生ThreadAbortException異常。 您可以使用try-catch語句來捕獲此異常。

Response.End方法結束頁面執行並將執行轉移到應用程序的事件管道中的Application_EndRequest事件。 不執行Response.End之后的代碼行。

Response.RedirectServer.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM