【发布时间】:2010-11-08 10:27:51
【问题描述】:
This KB Article 表示 ASP.NET 的 Response.End() 中止线程。
Reflector 显示它看起来像这样:
public void End()
{
if (this._context.IsInCancellablePeriod)
{
InternalSecurityPermissions.ControlThread.Assert();
Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
}
else if (!this._flushing)
{
this.Flush();
this._ended = true;
if (this._context.ApplicationInstance != null)
{
this._context.ApplicationInstance.CompleteRequest();
}
}
}
这对我来说似乎很苛刻。正如知识库文章所说,应用程序中Response.End() 之后的任何代码都不会被执行,这违反了最小惊讶原则。这几乎就像 WinForms 应用程序中的Application.Exit()。 Response.End() 导致的线程中止异常是无法捕获的,因此将代码包围在 try...finally 中不会满足。
这让我想知道我是否应该始终避免Response.End()。
谁能建议我什么时候应该使用Response.End(),什么时候应该使用Response.Close(),什么时候应该使用HttpContext.Current.ApplicationInstance.CompleteRequest()?
根据我收到的意见,我的回答是,是的,Response.End 是有害的,但它在某些有限的情况下很有用。
- 使用
Response.End()作为不可捕获的抛出,在异常情况下立即终止HttpResponse。在调试期间也很有用。 避免Response.End()完成例行回复。 - 使用
Response.Close()立即关闭与客户端的连接。根据this MSDN blog post,此方法不适用于正常的 HTTP 请求处理。您不太可能有充分的理由调用此方法。 - 使用
CompleteRequest()结束一个正常的请求。CompleteRequest导致 ASP.NET 管道在当前HttpApplication事件完成后跳转到EndRequest事件。因此,如果您调用CompleteRequest,然后在响应中写入更多内容,则写入内容将发送给客户端。
编辑 - 2011 年 4 月 13 日
此处提供了进一步的说明:
【问题讨论】:
-
不知道自这个答案以来发生了什么变化,但我正在赶上
Response.EndThreadAbortException就好了。 -
请记住,
Response.Redirect和Server.Transfer都调用Response.End,也应该避免使用。