ASP.NET Lab

The Best Web, The Best Future

博客园 首页 新随笔 订阅 管理

异步 HTTP 处理器允许你启动外部进程(比如一个调用远程服务器的方法),并且在无需等待外部进程被完成的情况之下继续处理器自身的处理。另外,在处理一个异步 HTTP 处理器的期间,ASP.NET 还会把通常用于外部进程的线程返回到线程池中,直到处理器从外部进程中接收到一个回调为止。这样能够防止线程阻塞并且能够改进性能,因为在同一时间内只有为数不多的线程才能够被执行。如果有许多用户请求了依赖于外部进程的同步 HTTP 处理器,那么操作系统就能够脱离线程而得到高速运行,因为许多线程都已经被阻塞并且需要等待外部进程的结束。

下列代码示范了一个在 ASP.NET 应用程序中对扩展名是 .SampleAsync 的文件的请求进行处理的异步 HTTP 处理器。这个范例说明了这个处理器的代码,然后说明了如何把扩展名 .SampleAsync 映射到 ASP.NET 中的处理器。最后,这个范例还说明了如何在 IIS 中把扩展名 .SampleAsync 映射到 ASP.NET,因此 IIS 会把以 .SampleAsync 为结尾的请求转送给 ASP.NET。

关于 ASP.NET 运行时如何与 IIS 相互作用的更多信息,请参考:[ASP.NET 应用程序生命周期概览]。

创建名为 HelloWorldAsyncHandler 的 HTTP 处理器类

  • 在你的 App_Code 目录中创建名为 HelloWorldAsyncHandler 的类并且添加下列代码到这个类文件中:
    using System;
    using System.Web;
    using System.Threading;
    
    class HelloWorldAsyncHandler : IHttpAsyncHandler
    {
        public bool IsReusable { get { return false; } }
    
        public HelloWorldAsyncHandler()
        {
        }
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
        {
            context.Response.Write("<p>Begin IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n");
            AsynchOperation asynch = new AsynchOperation(cb, context, extraData);
            asynch.StartAsyncWork();
            return asynch;
        }
    
        public void EndProcessRequest(IAsyncResult result)
        {
        }
    
        public void ProcessRequest(HttpContext context)
        {
            throw new InvalidOperationException();
        }
    }
    
    class AsynchOperation : IAsyncResult
    {
        private bool _completed;
        private Object _state;
        private AsyncCallback _callback;
        private HttpContext _context;
    
        bool IAsyncResult.IsCompleted { get { return _completed; } }
        WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } }
        Object IAsyncResult.AsyncState { get { return _state; } }
        bool IAsyncResult.CompletedSynchronously { get { return false; } }
    
        public AsynchOperation(AsyncCallback callback, HttpContext context, Object state)
        {
            _callback = callback;
            _context = context;
            _state = state;
            _completed = false;
        }
    
        public void StartAsyncWork()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null);
        }
    
        private void StartAsyncTask(Object workItemState)
        {
    
            _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n");
    
            _context.Response.Write("Hello World from Async Handler!");
            _completed = true;
            _callback(this);
        }
    }

    代码中实现了 BeginProcessRequest 方法。这个方法把一个字符串写入到了当前 HttpContext 对象的 Response 属性中,并且创建了 AsyncOperation 类的一个新实例,还调用了 StartAsyncWork 方法。然后 StartAsyncWork 方法会把 StartAsyncTask 代理添加到 ThreadPool 对象中。当线程开始生效的时候,StartAsyncTask 方法就会被调用,并且会输出另外一个字符串到 Response 属性中,然后通过调用 AsyncCallback 代理来完成其他任务。

注册自定义 HTTP 处理器

一旦你的自定义 HTTP 处理器类被创建,你就必须把它注册到 Web.config 文件中,这样 ASP.NET 才能够为扩展名是 .SampleAsync 的文件请求提供服务。

在 Web.config 文件中注册自定义 HTTP 处理器
  1. 如果你的 Web 站点中没有 Web.config 文件,就可以创建一个。
  2. 添加下列代码到你的 Web.config 文件中:
    <configuration>
      <system.web>
        <httpHandlers>
          <add verb="*" path="*.SampleAsync" 
            type="HelloWorldAsyncHandler"/>
        </httpHandlers>
      </system.web>
    </configuration>

    以上代码把 HelloWorldAsyncHandler 处理器注册成了对以 .SampleAsync 作为结尾的请求而提供服务的处理器。

在 IIS 中配置 HTTP 处理器扩展

IIS 只把特定文件类型的请求传递给 ASP.NET 的服务。默认时,扩展名是 .aspx、.ascx,.asmx 的文件都已经被映射到了 ASP.NET。但是,如果你需要 ASP.NET 处理自定义的文件扩展名,那么你就必须在 IIS 中进行注册。关于更多信息,请参考:[ASP.NET 应用程序生命周期概览]。

在 IIS 中映射扩展名
  1. 打开 Internet Services Manager。
  2. 右击你的应用程序并且选择 Properties。
  3. 在 Directory 标签中,点击 Configuration。
  4. 选择 Mappings 标签。
  5. 添加一个新关联把 .SampleAsync 映射到适当的 Aspnet_isapi.dll 版本。
  6. 如果你需要你的处理器在运行的时候不需要检测用户请求的文件是否已经存在,那么就可以清除 Check if the file exist 复选框。

测试自定义 HTTP 处理器

一旦你已经创建并且已经注册你的自定义 HTTP 处理器,那么你就可以通过从应用程序中发送一个扩展名是 .SampleAsync 的请求来对它进行测试。

测试你的自定义 HTTP 处理器
  • 浏览到你的应用程序并且在浏览器中输入一个以 .SampleAsync 作为结尾的 URL。
posted on 2007-03-15 12:26  Laeb  阅读(455)  评论(0编辑  收藏  举报