你必須知道的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.

五、求關注、求推薦

        兄台給點鼓勵吧,寫起來很真有點累.......行行好......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM