ASP.NET之自定义异步HTTP处理程序(图文教程)

一、前言

1.对读者想说的话:(可跳过)

在此我感谢那些看了《ASP.NET之自定义同步HTTP处理程序》这篇文章以及看到了这篇《ASP.NET 之 自定义 异步HTTP处理程序》的亲们。前面的那篇可能看过MSDN的亲们一定会发现很多熟悉的地方。而我其实就是比较详细的介绍了一下,让大家更好的理解

PS:MSDN从头到尾都是文字且文字很统一,恐怕很多人都感觉畏惧,懒的去看,所以我将其重要的部分提取出来,使用易懂的例子和简洁的语言来叙述。当然其中也免不了错误,希望各位亲们可以指出。

2.正式的开始

前面我们学习了关于关于自定义同步HTTP处理程序,相信大家可能感觉有所成就(大牛们可能会觉得so easy)。但是这种同步的机制只能对付客户访问较少的情况或者数据处理量不大的情况(每次申请一个同步HTTP处理程序都会新建一个新的线程来处理,当申请量很大时,线程将会被堵塞,致使服务器性能低下,甚至宕机)。而今天这篇文章就是解决同步HTTP处理程序的这个致命缺点,有效的使用服务器的资源。

PS:异步(仅限在本文章下的情况): 简单来说就是一部分操作在使用我们自己创建的线程,另一部分操作由操作系统调用自身的线程有条不紊的处理,这样我们可以将简单的处理由我们自身的线程完成,而复杂的处理则交给系统管理的线程来处理。因为这些线程是系统管理的所以不会出现卡死的情况,系统内部会自动的管理。当然系统会通过通知的方式告知我们的自己的线程该处理已经完成,这样我们就可以避免使用多线程技术,却难于管理的问题。

以下为图例:

二、注册与绑定(虽然前一篇已经讲述过,但是在这里仍然重新再讲一次)

为什么要有这两部呢?而且还是要注册与绑定这两个呢?

答案是 你只写一个类 vs是不可能知道你这个东西是干什么的,所以我们需要在 web.config 中注册我们自定义的HTTP处理程序。而绑定则是让iis知道我们这个站点中含有一个自定义的HTTP处理程序。(下面我将以 iis7 为例说明如何绑定)

1.注册


代码如下:

<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="<!-- 这里写需要绑定的客户端申请的页面(*.smm,*.ffs,web1.ffe) -->" type="<!-- 这里写处理程序的类名 -->"
</httpHandlers>
</system.web>
</configuration>

以上需要自行编写的部分我都已使用注释写好

2.绑定( iis7 )

1) 打开 iis7 -》 打开  网站  节点 -》 点击你的网站的名称

2) 双击

3) 点击

4)

5) 最后点击 确定 这样在 iis 中的绑定就完成了(后面的完整例子我将会以文字介绍该过程)

三、关于类的实现

这里我们将要实现两个接口的功能,下面我将分开来阐述

1. IHttpAsyncHandler 接口

需实现方法以及属性如下:

IAsyncResult BeginProcessRequest( HttpContext context , AsyncCallback cb , Object extradata ) 
   启动对HTTP处理程序的异步调用

参数说明:
                        context : 该对象提供对用于向 HTTP 请求提供服务的内部服务器对象(如 RequestResponseSessionServer)的引用。
                    cb : 当异步操作完成后调用该委托告知我们操作已经完成
                    extradata : 处理该请求所需的所有额外数据
  返回值:
                   返回有关进程状态的IAsyncResult (可以让我们时刻查看异步调用中的当前状态)

void EndProcessRequest( IAsyncResult result )
 进程结束时提供异步处理End方法

参数说明:
                          result : 有关进程状态的IAsyncResult(这里的result跟BeginProcessRequest返回的是同一个对象,只是内部的属性等等改变了)

注: 但是我们还要实现不在IHttpAsyncHandler接口中的一个属性和一个方法,否则IIS会报错

bool IsRusable
表明是否使用池,只需要实现get,返回false表示不使用,返回true表示使用。

void ProceessRequest( HttpContext context )
同步HTTP处理程序被调用的方法(这里并不会调用该方法,但是必须实现)

  2. IAsyncResutl 接口

需实现方法以及属性如下:

Object AsyncState
  获取用户定义的对象(其实就是以上的 extradata 并且只要实现get )

WaitHandler AsyncWaitHandle
  获取用于等待异步操作完成的 WaitHandle (一般都是返回NULL 并且只要实现get )  bool CompletedSynchronously
  获取异步操作是否同步完成的指示(一般都是返回false)  bool IsCompleted
  获取异步操作是否已完成的指示

  四、实现该功能(iis7 / asp.net 4.0 / vs2010 / windows 7 64bit )

注: 1.新建空web项目,并添加 App_Code 文件夹,并部署在 iis 上

2.在App_Code中新建一个类,命名为"AsyncRequestHandler.cs"(这里的命名不影响,但是类名是关键)

3.在 AsyncRequestHandler.cs 中引用 "System.Threading" 命名空间

下面我们将一步一步的学习实现这个功能,虽然只是一个很简单的例子,但是可以让你在以后的开发中更加灵活的运用。

1.实现 IHttpAsyncHandler 接口
代码如下:


代码如下:

public class AsyncHttpHandler : IHttpAsyncHandler
{
public AsyncHttpHandler()
{
//
//TODO: 在此处添加构造函数逻辑
//
}

public bool IsReusable
{
get
{
return false; //表明不使用池
}
}

public void ProcessRequest(HttpContext context) //不调用 必须实现的方法
{
throw new InvalidOperationException();
}

/// <summary>
/// 当客户申请时执行的异步处理
/// </summary>
/// <param name="context">包含httpresponse、httprequest、server对象</param>
/// <param name="cb">回调函数</param>
/// <param name="extradata">需要传递的参数</param>
/// <returns>返回有关进程的状态信息</returns>
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extradata) // 必须实现的方法
{
context.Response.Write("<p>AsyncHttpHandler</p>"); //向页面中写入html表明是该信息来自何处
AsyncOperation op = new AsyncOperation(context, cb, extradata); //实例化实现了 IAsyncResult 接口的类(主要实现异步处理的类)
op.StartAsyncWork(); //开始异步处理
return op; //返回该对象
}

/// <summary>
/// 当BeginProcessRequest中的 return op;与异步的处理完成后调用(调用完既呈现页面)
/// </summary>
/// <param name="result">为op,但是属性已改变</param>
public void EndProcessRequest(IAsyncResult result)
{
}
}

2.实现 IAsyncResult 接口(与上面的代码在同一个文件中)
代码如下:


代码如下:

public class AsyncOperation : IAsyncResult
{
HttpContext _context; //保存context的引用
AsyncCallback _cb;//保存回调委托的引用
object _state;//保存额外的信息
bool _iscomplate;//保存异步操作是否完成

/// <summary>
/// 构造函数,将AsyncHttpHandler的参数全部传递进来
/// </summary>
/// <param name="context"></param>
/// <param name="cb"></param> //该回调不可被重写,否则将会出现客户端永久等待的状态
/// <param name="state"></param> //构造时该值可以传递任意自己需要的数据
public AsyncOperation(HttpContext context, AsyncCallback cb, object state)
{
_context = context;
_cb = cb;
_state = state;
_iscomplate = false; //表明当前异步操作未完成
}

/// <summary>
/// 实现获得当前异步处理的状态
/// </summary>
bool IAsyncResult.IsCompleted
{
get
{
return _iscomplate;
}
}

/// <summary>
/// 返回 false 即可
/// </summary>
bool IAsyncResult.CompletedSynchronously
{
get
{
return false;
}
}

/// <summary>
/// 将返回额外的信息
/// </summary>
object IAsyncResult.AsyncState
{
get
{
return _state;
}
}

/// <summary>
/// 为空
/// </summary>
WaitHandle IAsyncResult.AsyncWaitHandle
{
get
{
return null;
}
}

/// <summary>
/// 表明开始异步处理的主函数(方法名可以改,但上面的调用也需要一起改)
/// </summary>
public void StartAsyncWork()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null);//相信很多玩国.net winform 开发的一定认识
}

/// <summary>
/// 异步操作调用的方法
/// </summary>
/// <param name="workstate">为QueueUserWorkItem方法中第二个参数传递的值</param>
public void StartAsyncTask(object workstate)
{
_context.Response.Write("<p>Completion IsThreadPoolThread is" + Thread.CurrentThread.IsThreadPoolThread + "</p>");
_iscomplate = true; //表明异步操作已完成
_cb(this);//调用回调函数表明完成
}
}

3.web.config 配置

内容如下(红色方框部分为需要添加的内容):

4.iis绑定(如何绑定见 二 )

5.测试

时你随意的写  test.async 或者  asd.async 等等,最后呈现的页面都是一致的。这样就达到我们的效果了

五、看完这些只是浅层

这里我想指明的是看完这些并不代表你已经掌握了所有,因为关于异步还有一个部分就是共享资源的使用,这个就需要使用到 WaitHandle 类,否则就会导致多个线程同时访问并修改同一个共享资源,后果可想而知。所以在这篇文章完结的同时也意味着新的问题的开始,所以我们要不断的学习下去。

(0)

相关推荐

  • asp.net 未能加载文件或程序集“XXX”或它的某一个依赖项。试图加载格式不正确的程序。

    说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常详细信息: System.BadImageFormatException: 未能加载文件或程序集"XXX"或它的某一个依赖项.试图加载格式不正确的程序. 源错误: 执行当前 Web 请求期间生成了未处理的异常.可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息. 程序集加载跟踪: 下列信息有助于确定程序集"XXX"无法加载的

  • asp.net+jquery滚动滚动条加载数据的下拉控件

    这样的需求貌似自己感觉不是很合理,因为数据多了如此下拉无论从人还是机器操作都比较痛苦. 没办法由于需求下来了,只能按需求操作.网上找了很多相关控件都感觉有点庞大,占资源比较多.没办法自己花半天时间弄出个半成品自定义控件,拿出来分享下,如有高手看了请多指点. 需求:AJAX滚动滚动条加载数据的下拉列表 控件名称:Webcombo 所用技术:ASP.NET(C#),jQuery,ASP.NET一般处理文件(.ashx) 下拉列表具体实现:用DIV模拟下拉列表,input和图片模拟下拉框.最终结果如下

  • asp.net动态加载用户控件,关于后台添加、修改的思考

    看下下面这个典型的后台(比较粗糙):说实在,我很厌倦全部用.aspx文件去做,比如"友情连接"这个模块,就有"添加友情连接""修改友情连接""友情连接列表",简单的话,可以把"添加""修改"合成一个文件.每次都去建立一个.aspx文件.我现在的想法是用"用户控件+配置文件"去实现,虽然文件数目可能不会少很多.但在编程到一定地步,我想大家会有跟我一样的想法. 首先需要涉

  • Asp.net利用JQuery弹出层加载数据代码

    首先我们新建一个网站,在网站里面新增一般处理程序,命名为ReadData.ashx.然后在里面输入如下代码: 复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Data.SqlClient; //引入命名空间 using System.Data; namespace 加载层 {

  • asp.net+ajaxfileupload.js 实现文件异步上传代码分享

    由于代码很简单,这里就闲话不多说了,直接上代码,小伙伴们自己研读代码就明白了. 前台代码: 复制代码 代码如下: /*修改头像*/      //上传      function _sc() {          $(".ckfile").html("").css("color", "#535353");          $("#_userImgPath").val("");     

  • jquery异步调用页面后台方法&#8207;(asp.net)

    复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="JqueryCSMethodForm.aspx.cs" Inherits="JQuerWeb.JqueryCSMethodForm" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&

  • JQuery FlexiGrid的asp.net完美解决方案 dotNetFlexGrid-.Net原生的异步表格控件

    dotNetFlexGrid是一款asp.net原生的异步表格控件,他的前身是Jquery FlexiGrid插件,我们重构了FlexiGrid的大部分Javascript代码,使其工作的更有效率,BUG更少:同时将其封装为dotNet控件,提供了简单易用的使用方式. dotNetFlexGrid扩展和优化了FlexiGrid原有的功能,并提供了更多具有针对性的功能,使用dotNetFlexGrid,您的用户可以轻松拥有如下功能 提供简易的方式自行调整表格列宽 根据实际情况调整表格的大小 针对合

  • asp.net下实现支持文件分块多点异步上传的 Web Services

    本文的客户端应用程序不包括 ASP.Net Web 应用程序! 本文假设 URL: http://localhost/mywebservices/updownload.asmx 共有 4 个程序文件 (Web.Config 就不赘述了) Server Side: 标题中所提到的 "异步" 其实在服务器端的程序并没有什么特殊的,而主要是通过客户端应用程序 异步调用相关 Web Method 实现的! 1. updownload.asmx ,位于 IIS 的某个 Web 共享目录,代码如下

  • asp.net下的异步加载

    具体我本身大概用的就有两种,需配合JQ. 第一种,直接通过AJAX去请求页面:例如, 1:dataType必须是html或者Text格式, 2:Type:必须是'Post'请求 3:后台Load事件必须判断是否为Post请求 后台代码如下: 测试结果如下: 第二种:类似于.net MVC直接请求方法. 1:后台代码中,引入using System.Web.Services; 2:方法必须是静态修饰,且方法上面打上特性 [WebMethod] 3:在JQ中返回成功回调函数内获取数据必须是 返回名字

  • asp.net jquery+ajax异步刷新实现示例

    复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title

随机推荐