一、寫在前面
一說到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.
五、求關注、求推薦
兄台給點鼓勵吧,寫起來很真有點累.......行行好......