Response.End()不会中止当前线程
有人知道为什么ASP.NET可能不会使用Response.End()中止当前线程吗?
更新:原因是有一些代码,尽管编写得不好,但是在Response.End()之后执行。 我从未见过Response.End()没有阻止当前线程执行的情况。
protected void Page_Load(object sender, EventArgs e) { Response.Clear(); Response.Redirect("somewhere", true); Response.End(); //Some other code get's executed here }
正如您所指出的,Response.End方法定义为:
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(); } } }
使用Page_Load方法中的断点调试一个相当简单的Web应用程序,我可以看到调用堆栈包含以下行:
System.Web.dll中! System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step = {System.Web.HttpApplication.CallHandlerExecutionStep},ref bool completedSynchronously = true)+ 0x4c bytes
反映到CallHandlerExecutionStep
我可以看到属性IsCancellable
定义为:
bool HttpApplication.IExecutionStep.IsCancellable { get { return !(this._application.Context.Handler is IHttpAsyncHandler); } }
.aspx页面的默认处理程序是PageHandlerFactory
的输出,它实现了IHttpHandler,而不是PageHandlerFactory
– 这将导致IsCancellable
返回true(就像在我的测试应用程序中一样)。
您是否在根web.config中配置了不同的HttpHandler,或者在堆栈中的另一个上配置了不同的HttpHandler以使用异步处理程序? 您是否正在使用具有部分回发的更新面板?
你没有在试试块中拥有它吗? 这将抛出ThreadAbortException。
根据社区对http://msdn.microsoft.com/en-us/library/a8wa7sdt (VS.80) .aspx (选择.NET framework 2.0)的评论,当前线程在Global.asax中是不可取消的:
“小心!!如果你传递了true,Response.Redirect()会调用Response.End(),但是在某些情况下,Response.End()不会引发ThreadAbortException,而是设置一些标志并返回。一个这样的情况当你在Global.asax时,但它会在任何不可取消的执行步骤中更一般地发生。我将在Response.End()上添加详细信息,但是在页面中你可以,但在全局.asax处理将继续进行,即使你将第二个parm传递给了true。“
我实际上在我的一个项目中注意到了这种行为。
我可能会弄错,但我相信一方面,使用的线程是属于线程池的后台线程,并且被回收,所以它不会杀死线程。
Response.End()终止响应,但它不从函数返回。
protected void Page_Load(object sender, EventArgs e) { If(sometingBad) { Response.Clear(); Response.Redirect("somewhere", true); Response.End(); return; } //Some other code get's executed here }