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.

    五、求关注、求推荐

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

  • 相关阅读:
    Python 安装Twisted 提示python version 2.7 required,which was not found in the registry
    Openfire Strophe开发中文乱码问题
    css div 垂直居中
    How to create custom methods for use in spring security expression language annotations
    How to check “hasRole” in Java Code with Spring Security?
    Android 显示/隐藏 应用图标
    Android 当媒体变更后,通知其他应用重新扫描
    文件上传那些事儿
    专题:点滴Javascript
    主流动画实现方式总结
  • 原文地址:https://www.cnblogs.com/humble/p/3922061.html
Copyright © 2011-2022 走看看