【问题标题】:Response.End () doesn't abort current threadResponse.End () 不会中止当前线程
【发布时间】:2010-02-02 00:10:11
【问题描述】:

有人知道为什么 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
}

【问题讨论】:

  • 为什么中止线程?当然,该线程只会回到线程池中。 (警告:自 1999 年以来,我没有研究过 ASP 的线程模型;自从我上次查看该代码以来,情况可能已经发生了变化。)
  • Response.End() 确实中止了线程。 support.microsoft.com/kb/312629
  • @Cheeso,它应该,但我的情况是有些事情正在阻止。 Rick Strahl 有一个小代码 sn-p,它显示了一个不会中止当前线程的潜在情况。 west-wind.com/WebLog/posts/368975.aspx
  • @Trent,但即使他也不知道它为什么起作用,这有点微妙的错误 - 看看它应该如何工作,应该继续引发异常在他接球之后,仍然没有记录他的横幅呼叫。
  • @Zhaph,我真的指的是他概述的 MS 正在做什么的代码 in 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._end = true; if (this._context.ApplicationInstance != null) { this._context.ApplicationInstance.CompleteRequest(); } } }

标签: c# asp.net


【解决方案1】:

正如您所指出的,方法 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 字节

反射到CallHandlerExecutionStep可以看到属性IsCancellable定义为:

bool HttpApplication.IExecutionStep.IsCancellable {
  get {
    return !(this._application.Context.Handler is IHttpAsyncHandler);
  }
}

.aspx 页面的默认处理程序是实现 IHttpHandler 的 PageHandlerFactory 的输出,而不是 IHttpAsyncHandler - 这将导致 IsCancellable 返回 true(就像在我的测试应用程序中一样)。

您是否在您的根 web.config 或堆栈中配置了不同的 HttpHandler 以使用异步处理程序来代替?例如,您是否使用带有部分回发的更新面板?

【讨论】:

  • 干得好。当前的代码库对我来说有点新,但我知道那里有一些处理程序。我的第一个嫌疑人是一个 ISAPI 重写插件,但这些处理程序可能有一些东西。
【解决方案2】:

您没有在 try 块中使用它吗?那会抛出一个 ThreadAbortException。

【讨论】:

    【解决方案3】:

    根据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() 上添加详细信息,但在一个页面中你会没事的,但在 Global.asax 中,即使您将 true 作为第二个参数传递,处理也会继续。"

    我实际上在我的一个项目中注意到了这种行为。

    【讨论】:

      【解决方案4】:

      我可能弄错了,但我相信一方面,所使用的线程是属于线程池的后台线程,并且会被回收,因此它不会杀死线程。

      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 
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-08
        • 2010-09-26
        • 2019-08-03
        • 1970-01-01
        • 1970-01-01
        • 2017-02-25
        • 1970-01-01
        相关资源
        最近更新 更多