ASP.NET 1.x 本质上不支持异步页,但是通过坚韧的努力和不懈地创新可以生成异步页。有关更多概述信息,请参阅相关资料
这里的技巧是,在一个页的代码隐藏类中实现 IhttpAsyncHandler,从而提示 ASP.NET 通过调用 IHttpAsyncHandler.BeginProcessRequest 来处理请求,而不是通过调用该页的 IHttpHandler.ProcessRequest 方法。然后,您的 BeginProcessRequest 实现可以启动另一个线程。该线程调用 base.ProcessRequest,使得页进入其常规请求处理生命周期(完成诸如 Load 和 Render 的事件),但是在非 ThreadPool 线程上例外。同时,启动新线程之后 BeginProcessRequest 立即返回,从而允许执行 BeginProcessRequest 的线程返回线程池。
这是基本思想,但细节中还有很多注意事项。其中,您需要实现 IAsyncResult,并从 BeginProcessRequest 中返回它。这通常意味着创建一个 ManualResetEvent 对象,并且当 ProcessRequest 在后台线程中返回时向其发送信号。此外,您必须提供调用 base.ProcessRequest 的线程。遗憾的是,多数用于将工作移到后台线程的常规技术(包括 Thread.Start、ThreadPool.QueueUserWorkItem 和异步委托)在 ASP.NET 应用程序中都是起反作用的,因为它们或者从线程池“偷盗”线程,或者有不受限制的线程增长的危险。正确的异步页实现使用自定义线程池,但自定义线程池类不容易编写。
主要是在 ASP.NET 1.x 中生成异步页并非不可能,而是有些乏味。在尝试一、两次之后,您不禁会想一定会有更好的方法。目前,这个好方法就是 ASP.NET 2.0。
ASP.NET 2.0 极大地简化了生成异步页的方式。首先使用该页的 @ Page 指令引入 Async=“true” 属性,如下所示:
在后台,这会通知 ASP.NET 在该页中实现 IhttpAsyncHandler。接下来,您在该页生存期的早期(例如,在 Page_Load 时)调用新的 Page.AddOnPreRenderCompleteAsync 方法来注册一个 Begin 方法和一个 End 方法,