首页 > 代码库 > 你必须知道的ASP.NET-----IHttpAsyncHandler实质

你必须知道的ASP.NET-----IHttpAsyncHandler实质

一、写在前面

  一说到IHttpAsyncHandler,很多人会顾名思义地说‘不就是异步IHttpHandler‘吗?

但当我发出疑问:"你真知道他们的不同之处?你真会使用它吗?",这个时候估计就要扑倒一堆人.

下面我将如同以前的风格分析它,不足之处求指正.

二、关于IHttpAsyncHandler的概述

  微软给出的定义很简单:定义 HTTP 异步处理程序对象必须实现的协定

从下面的源代码中,我们很容易看出,它继承了IHttpHandler的接口规范.同时多了两个方法

BeginProcessRequest和EndProcessRequest方法.
using System;namespace System.Web{    public interface IHttpAsyncHandler : IHttpHandler    {        IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);        void EndProcessRequest(IAsyncResult result);    }}
using System;namespace System.Web{    public interface IHttpHandler    {        bool IsReusable        {            get;        }        void ProcessRequest(HttpContext context);    }}

  但问题来了:它是怎样达到异步效果的呢?亦即:有怎样的异步效果?如何实现这一异步效果的呢?

 

三、IHttpAsyncHandler深入理解

1)为什么能够异步?

  有些人或许会觉得IHttpAsyncHandler嘛,当然是异步的了.我想问问:老婆面是不是有老婆呢?

        有了它真的会异步吗?但我们知道:不是自己本身进行了特殊处理,就是使用者对他进行了特殊对待(或特殊处理)

        容我大胆的推测.net自己没有对他特殊处理

  我的依据如下(当然你可以说这是httpapplication的,但足以让我用来推论),.net只是判断 他的类型,调用不一样的入口而已.

         if (applicationInstance is IHttpAsyncHandler)                {                    IHttpAsyncHandler httpAsyncHandler = (IHttpAsyncHandler)applicationInstance;                    httpContext.AsyncAppHandler = httpAsyncHandler;                    httpAsyncHandler.BeginProcessRequest(httpContext, this._handlerCompletionCallback, httpContext);                }                else                {                    applicationInstance.ProcessRequest(httpContext);                    this.FinishRequest(httpContext.WorkerRequest, httpContext, null);                }

 

  所以:最终我不太负责任地告诉大家,异步本身是它自己内部的代码实现的.外部调用只是调用了不同的入口(BeginProcessRequest)

即他并非没有什么了不起,只是一个接口只是一个规范问题.

2)如何异步?

  做过多线程的朋友,估计都知道如何实现多线程(异步),方法较多.但本质就一个(用额外的线程去处理耗时间的事情)这里,我简单地线程池的方式进行分解‘如何实现异步‘----ThreadPool.QueueUserWorkItem 方法 

  这里给出微软的定义:将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。说得很简单,但是理解起来似乎不太容易理解什么放入队列.我的理解如下:在线程池的内部有一个队列用于存放所有需要做的事情,

线程池有自己的一堆动态的线程(相当于搬运工),他们随机地去完成队列中的事情.  

  关于该方法的说明:

callBack

类型:System.Threading.WaitCallback
WaitCallback ,它表示要执行的方法。
state
类型:System.Object
包含方法所用数据的对象。

返回值

类型:System.Boolean
如果此方法成功排队,则为 true;如果无法将该工作项排队,则引发 NotSupportedException。

   好了,我们多的不说了.看看如何实现IHttpAsyncHandler异步.看下面的实例源代码

四、实例

using System;using System.Web;using System.Threading;namespace Handler_1{        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)        {            Thread.Sleep(3000);            _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);        }    }}

 

说明:当外面调用这个异步handler的时候,会一次性返回给浏览器,不要看有很多Write.

五、求关注、求推荐

        兄台给点鼓励吧,写起来很真有点累.......行行好......