Context.Response.End()和Thread正在中止

时间:2010-03-04 09:50:41

标签: asp.net

我正在尝试使用Context.Response.End关闭回复,但收到错误"Thread was being aborted"

如何在不触发异常的情况下正确关闭响应?

try {
   Context.Response.Clear();
   Context.Response.ContentType = "text/html"; 
   //Context.Response.ContentType = "application/json";
   JsonObjectCollection collection = new JsonObjectCollection();
   collection.Add(new JsonNumericValue("resultcode", 1));
   collection.Add(new JsonStringValue("sourceurl", exchangeData.cUrl));
   collection.Add(new JsonStringValue("filename", fileName));
   collection.Add(new JsonStringValue("filesize", fileSize));
   collection.Add(new JsonStringValue("fileurl", Common.GetPDFURL + outputFileName));
   JsonUtility.GenerateIndentedJsonText = true;
   Context.Response.Write(collection);
  try {
     Context.Response.End();
  } catch (ThreadAbortException exc) {
     // This should be first catch block i.e. before generic Exception
     // This Catch block is to absorb exception thrown by Response.End
  }
} catch (Exception err) {

}

由我自己解决,代码应该看起来像

try {
  Context.Response.End();
} catch (ThreadAbortException err) {

}
catch (Exception err) {
}

6 个答案:

答案 0 :(得分:26)

您是否有使用context.ApplicationInstance.CompleteRequest()的具体原因?

此方法会短路ASP.NET管道(EndRequest事件除外)而不会抛出ThreadAbortException,因此您不需要额外的try / catch块,并且你也会体验到更好的表现。

答案 1 :(得分:8)

尝试 response.OutputStream.Close(); 而不是 response.End(); 这会有所帮助!

答案 2 :(得分:2)

错误:线程正在中止。在System.Web.HttpResponse.End()

的System.Threading.Thread.Abort(Object stateInfo)上的System.Threading.Thread.AbortInternal()处

如果您使用Response.End,Response.Redirect或Server.Transfer

,则会发生此错误

原因:Response.End方法结束页面执行并将执行转移到应用程序事件管道中的Application_EndRequest事件。不执行Response.End之后的代码行。

Response.Redirect和Server.Transfer方法中出现此问题,因为两个方法都在内部调用Response.End。

分辨率/解决方案:

您可以使用try-catch语句来捕获此异常

对于Response.End,调用HttpContext.Current.ApplicationInstance.CompleteRequest方法而不是Response.End来绕过代码执行到Application_EndRequest事件。对于Response.Redirect,使用一个重载,Response.Redirect(String url,bool endResponse),它为endResponse参数传递false以禁止对Response.End的内部调用。例如:ex:Response.Redirect(“nextpage.aspx”,false);如果使用此变通方法,则执行Response.Redirect之后的代码。对于Server.Transfer,请改用Server.Execute方法。

答案 3 :(得分:0)

我推荐这个解决方案:

  1. 不要使用response.End();

  2. 声明此全局变量:bool isFileDownLoad;

  3. 就在你的(response.Write(sw.ToString());)set ==>之后isFileDownLoad = true;

  4. 覆盖您的渲染,如:

    /// /// AEG:处理线程中止异常非常重要 /// /// override protected void Render(HtmlTextWriter w) {     if(!isFileDownLoad)base.Render(w); }

答案 4 :(得分:0)

或者您可以将 context.Response.End()置于finally bloc 中。这样你就不必关心不受欢迎的ThreadAbortException,也不会忽略真正的ThreadAbortException(这很糟糕)。您也不会忽略管道阶段。

try
{
    context.Response.ContentType = "application/json";
    context.Response.ContentEncoding = Encoding.UTF8;

    if (NotAuthorized())
    {
        context.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
        return;
    }

    context.Response.Write(MakeJsonStuff());
}
catch (Exception ex)
{
    LogException(ex);

    context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
    context.Response.Write(MakeJsonError(ex));
}
finally
{
    context.Response.End();
}

答案 5 :(得分:0)

这有助于我处理Thread was being aborted例外,

try
{
   //Write HTTP output
    HttpContext.Current.Response.Write(Data);
}  
catch (Exception exc) {}
finally {
   try 
    {
      //stop processing the script and return the current result
      HttpContext.Current.Response.End();
     } 
   catch (Exception ex) {} 
   finally {
        //Sends the response buffer
        HttpContext.Current.Response.Flush();
        // Prevents any other content from being sent to the browser
        HttpContext.Current.Response.SuppressContent = true;
        //Directs the thread to finish, bypassing additional processing
        HttpContext.Current.ApplicationInstance.CompleteRequest();
        //Suspends the current thread
        Thread.Sleep(1);
     }
   }

如果您使用以下代码而不是HttpContext.Current.Response.End(),则会获得Server cannot append header after HTTP headers have been sent例外。

            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.SuppressContent = True;
            HttpContext.Current.ApplicationInstance.CompleteRequest();

我发现的另一个修复是Thread.BeginCriticalRegion();

   try 
 {
    //Write HTTP output
   HttpContext.Current.Response.Write(Data);
  } catch (Exception exc) {} 
  finally {
    try {
     //Notifies a host that execution is about to enter a region of code in which the effects of a thread abort or unhandled exception might jeopardize other tasks in the application domain.
     Thread.BeginCriticalRegion();
     HttpContext.Current.Response.End();
         } catch (Exception ex) {} 
    finally {
    //Sends the response buffer
    HttpContext.Current.Response.Flush();
    // Prevents any other content from being sent to the browser
    HttpContext.Current.Response.SuppressContent = true;
    //Directs the thread to finish, bypassing additional processing
    HttpContext.Current.ApplicationInstance.CompleteRequest();
    Thread.EndCriticalRegion();
         }
   }

希望有所帮助