ASP.NET之自定义异步HTTP处理程序(图文教程)
前面我们学习了关于关于自定义同步HTTP处理程序,相信大家可能感觉有所成就,但是这种同步的机制只能对付客户访问较少的情况或者数据处理量不大的情况,而今天这篇文章就是解决同步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 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。 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 类,否则就会导致多个线程同时访问并修改同一个共享资源,后果可想而知。所以在这篇文章完结的同时也意味着新的问题的开始,所以我们要不断的学习下去
详细出处参考:http://www.jb51.net/article/33026.htm
ASP.NET之自定义异步HTTP处理程序(图文教程)的更多相关文章
- maven怎么引入自定义jar的详细图文教程
1 首先找到你的maven的配置文件{你maven的路径}\conf\settings.xml,然后打开settings.xml,并修改你存放本地jar路径.如我想把我自己的jar放到C:\Users ...
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...
- ASP.NET线程与异步
什么是线程? 线程简单来说就是一种数据结构,用来管理这个程序的执行状态,其中包括 1.线程核心对象->寄存器的状态 2.线程环境块,是一块用户模式下的内存,包含线程的异常处理链的头部.线程的局部 ...
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装
在asp.net项目中,添加一个[一般处理程序]来处理请求是很自然的事,这样会得到一个实现自IHttpHandler的类,然后只需在ProcessRequest方法中写上处理逻辑就行了.但是这样的一个 ...
- ASP模拟POST请求异步提交数据的方法
这篇文章主要介绍了ASP模拟POST请求异步提交数据的方法,本文使用MSXML2.SERVERXMLHTTP.3.0实现POST请求,需要的朋友可以参考下 有时需要获取远程网站的某些信息,而服务器又限 ...
- asp.net mvc 自定义pager封装与优化
asp.net mvc 自定义pager封装与优化 Intro 之前做了一个通用的分页组件,但是有些不足,从翻页事件和分页样式都融合在后台代码中,到翻页事件可以自定义,再到翻页和样式都和代码分离, 自 ...
- ASP.NET MVC 自定义路由中几个需要注意的小细节
本文主要记录在ASP.NET MVC自定义路由时,一个需要注意的参数设置小细节. 举例来说,就是在访问 http://localhost/Home/About/arg1/arg2/arg3 这样的自定 ...
- 在ASP.NET开始执行HTTP请求的处理程序之前
using Dscf.Client.Web.Class; using Dscf.Client.Web.DscfService; using Dscf.Client.Web.Handler; using ...
- Asp.net Mvc 自定义Session (二)
在 Asp.net Mvc 自定义Session (一)中我们把数据缓存工具类写好了,今天在我们在这篇把 剩下的自定义Session写完 首先还请大家跟着我的思路一步步的来实现,既然我们要自定义Ses ...
随机推荐
- 力挺8天入门wpf【转载】
8天入门wpf—— 第八天 最后的补充 摘要: 从这一篇往前看,其实wpf中还有很多东西没有讲到,不过我的原则还是将比较常用的知识点过一遍,如果大家熟悉了这些知识,基本功也就打的差不多了,后续可以等待 ...
- 并查集+二分-hdu-4750-Count The Pairs
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4750 题目大意: 给一无向图,n个点,m条边,每条边有个长度,且不一样.定义f(i,j)表示从节点i ...
- 在Android中建立Android project没有R.java文件
最近在搞一下安卓,在新建Android工程,既然发现在gen目录下没有R.java这个文件.我当时感到很郁闷,上次建Android工程才好好的,怎么这次既然报错没有R.java.后来我用以下才解决了. ...
- SSH框架-unexpected token: * near line 1, column 8 [select * from tb_chaper where course_id = 2];报错解决方法
SSH项目,访问jsp页面出现报错,控制台显示报错信息: org.springframework.orm.hibernate3.HibernateQueryException: unexpected ...
- python 笔记2--函数
函数变量 >>> a = abs # 变量a指向abs函数 >>> a(-1) # 所以也可以通过a调用abs函数 1 定义函数 def my_abs(x): if ...
- /boot磁盘空间不足,没盘扩展,只好删除旧内核了
[xiejdm@localhost ~]$ uname -r -.el7.x86_64 [xiejdm@localhost ~]$ sudo rpm -qa | grep kernel kernel- ...
- Aandroid Error之 新导入工程报Unable to resolve target 'android-18'和R cannot be resolved
有段时间没有写安卓了,今天导入以前的项目,结果看到控制台打印出了这样一句:Unable to resolve target 'android-18', 解决方法: 项目->属性->Andr ...
- MySQL 初学笔记 ② -- MySQL安装
1. Ubuntu安装 sudo apt-get install mysql-server //安装mysql服务 sudo apt-get install mysql-client // sudo ...
- python 2.6升级到2.7
CentOS 6.5上安装的python版本是2.6.6,不能满足我运行软件的要求,所以对python进行升级. 原以为这也就是安装个软件的事儿,在我求稳搜索一下了之后发现,也并不是那么单纯简单. 下 ...
- node.js中favicon.ico请求两次问题
var http=require("http"); var server=http.createServer(); server.on("request",fu ...