zoukankan      html  css  js  c++  java
  • 你必须知道的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>
    ");
                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>
    ");
    
                _context.Response.Write("Hello World from Async Handler!");
                _completed = true;
                _callback(this);
            }
        }
    }

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

    五、求关注、求推荐

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

  • 相关阅读:
    JavaScript笔试必备语句
    JQuery获取元素的方法总结
    JavaScript易错知识点整理
    程序员都讨厌开会?
    JS操作select下拉框动态变动(创建/删除/获取)
    用 jQuery.ajaxSetup 实现对请求和响应数据的过滤
    HTML5 学习笔记(一)——HTML5概要与新增标签
    json返回数据库的时间格式为/Date(1477294037000)/,怎样在前台进行格式化转换
    Hive 12、Hive优化
    Hive 11、Hive嵌入Python
  • 原文地址:https://www.cnblogs.com/humble/p/3922061.html
Copyright © 2011-2022 走看看