你必须知道的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
包含方法所用数据的对象。
好了,我们多的不说了.看看如何实现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.
五、求关注、求推荐
兄台给点鼓励吧,写起来很真有点累.......行行好......