我正在尝试使用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) {
}
答案 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)
我推荐这个解决方案:
不要使用response.End();
声明此全局变量:bool isFileDownLoad;
就在你的(response.Write(sw.ToString());)set ==>之后isFileDownLoad = true;
覆盖您的渲染,如:
/// /// 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();
}
}
希望有所帮助