【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装
在asp.net项目中,添加一个【一般处理程序】来处理请求是很自然的事,这样会得到一个实现自IHttpHandler的类,然后只需在ProcessRequest方法中写上处理逻辑就行了。但是这样的一个请求处理程序(下称ashx)是同步的,就是接待该次请求的线程会一直等待处理完才能解脱,后果就是,如果这个ashx比较耗时,并且同时对它的请求又多的话,服务器需要开启若干个线程来跑这个ashx,并且这些线程都要各自跑很久才能被收回或挪作它用,如果这样的ashx还有不少的话,那么对整个服务器资源的开销是很大的,所以有必要采用IHttpAsyncHandler来实现这种ashx,即异步请求处理程序,异步化以后,线程把请求接进来就完事了,反手就可以去处理其它请求,然后由别的线程或硬件来处理具体的任务~取决于任务是CPU消耗型(密集运算,如图片处理)还是I/O型(数据库读写、网络访问等),老实说如果耗时任务总是CPU消耗型,那同步异步在资源消耗上没什么区别,因为总得有个线程来跑任务,换不换线程意义不大。但总的来说异步化没坏处,而且万一对任务类型评估错误呢。
改用IHttpAsyncHandler后,多了两个方法BeginProcessRequest和EndProcessRequest,原有的ProcessRequest事实上已经废弃,请求不会进入里面,而是改为在BeginProcessRequest中处理请求,原IsReusable属性功能不变。说回BeginProcessRequest,这是一个典型的传统异步方法(相对于.net 4.5后的async/await新式异步方法来说),逻辑相比原来的同步方法ProcessRequest有点绕,首先入参除了熟悉的HttpContext外还有两个,然后还有个IAsyncResult类型的返回值。熟悉APM(异步编程模型)套路的朋友知道该怎么搞,不熟悉的可参看MSDN,要点就是实例化一个实现IAsyncResult的类,在其中异步或起线程执行逻辑,然后返回这个对象。现成的实现IAsyncResult的类在.net 4.0后有Task,但如果项目不到4.0,你还找不到一个可以拿来就用的类,如果要为每个ashx实现一个IAsyncResult,想想都蛋疼,哪怕总共只需实现一个IAsyncResult我都不情愿,好在委托这个东西编译器会为它自动生成异步模型,于是有了下面这个简单的封装:
/// <summary>
/// 异步请求处理基类
/// <para>- 子类实现ProcessRequest方法并在其中处理请求</para>
/// <para>- 默认允许实例重用(IsReusable=true),子类可重写为false</para>
/// </summary>
public abstract class HttpAsyncHandler : IHttpAsyncHandler
{
readonly Action<HttpContext> _processRequestDel; protected HttpAsyncHandler() => _processRequestDel = ProcessRequest; /// <summary>
/// 处理请求
/// </summary>
//总是要有个让子类处理业务逻辑的地方,既然原来的ProcessRequest已废弃,不如废物利用
public abstract void ProcessRequest(HttpContext context); /// <summary>
/// 多次请求是否可以重用实例。默认true
/// </summary>
public virtual bool IsReusable => true; public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) =>
_processRequestDel.BeginInvoke(context, cb, extraData); //利用ProcessRequest委托的异步能力 //虽然不End也不会导致异步还没跑完就返回响应(HttpApplication的实现似乎保证这一点),但异步中抛出的异常会被忽略,所以需要End暴露问题
public void EndProcessRequest(IAsyncResult result) => _processRequestDel.EndInvoke(result);
}
有了这个封装好的基类,在写新的ashx时就可以把IHttpHandler改为HttpAsyncHandler,完了把ProcessRequest方法标成override就行,老ashx也可以经过简单修改异步化。举例:
public class FooHandler : HttpAsyncHandler // 替掉IHttpHandler
{
//加上override
public override void ProcessRequest(HttpContext context)
{
//在这里写逻辑
context.Response.Write("OK");
}
}
需要注意的是IsReusable在HttpAsyncHandler中已改为true,所以如果你的ashx明确需要false,请override该属性,如:
public override bool IsReusable => false;
对于.net 4.5及以上版本,微软已经写好了个HttpTaskAsyncHandler,性质一样,只不过形式上符合新式的async/await用法,总之目的都是让开发者可以优雅的使用异步ashx,不必繁琐的从IHttpAsyncHandler开始。
EOF
【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装的更多相关文章
- 普通B/S架构模式同步请求与AJAX异步请求区别(个人理解)
在上次面试的时候有被问到过AJAX同步与异步之间的概念问题,之前没有涉及到异步与同步的知识,所以特意脑补了一下,不是很全面... 同步请求流程:提交请求(POST/GET表单相似的提交操作)---服务 ...
- 同步请求和异步请求的区别(理解ajax用)
同步请求:发送方发送数据包后,等待接收方发回响应之后,才能发送下一个数据包的通信方式. 异步请求:发送方发送数据包后,不用等待接收方发回响应,就可以发送下一个数据包的通信方式. 同步通信:要求通信双方 ...
- SpringBoot异步请求
何为异步请求 在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理.如果一个请求需要进行IO操作,比如 ...
- SpringBoot | 第二十章:异步开发之异步请求
前言 关于web开发的相关知识点,后续有补充时再开续写了.比如webService服务.发邮件等,这些一般上觉得不完全属于web开发方面的,而且目前webService作为一个接口来提供服务的机会应该 ...
- tornado异步请求的理解(转)
tornado异步请求的理解 http://www.kankanews.com/ICkengine/archives/88953.shtml 官网第一段话: Tornado is a Python w ...
- 同步请求和异步请求的区别,ajax异步请求如何理解
同步请求和异步请求的区别 先解释一下同步和异步的概念 同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式. 异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的 ...
- 深入理解Servlet3.0异步请求
异步请求的基础概念 异步请求最直接的用法就是处理耗时业务,Http协议是单向的,只能客户端拉不能服务器主推. 异步请求的核心原理主要分为两大类:1.轮询.2长连接 轮询:就是定时获取返回结果. 长连接 ...
- ASP.NET之自定义异步HTTP处理程序(图文教程)
前面我们学习了关于关于自定义同步HTTP处理程序,相信大家可能感觉有所成就,但是这种同步的机制只能对付客户访问较少的情况或者数据处理量不大的情况,而今天这篇文章就是解决同步HTTP处理程序的这个致命缺 ...
- JavaScript处理异步请求的几种方式(取异步函数返回值)
JavaScript处理异步的几种方式 Javascript语言的执行环境是"单线程"(single thread,就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个 ...
随机推荐
- 一张图解释NIO原理
- 报表软件公司高价悬赏BUG,100块1个我真是醉了
一直在用帆软的报表软件FineReport来做项目,也一直关注着这个公司的发展. 看到<提BUG,拿奖金>的这个活动,有些疑问和思考. 一般FineReport新版本在正式发布前,都会经过 ...
- ITU-T E.800 有关服务质量(QoS)的术语定义
摘要 ITU-T E.800建议书为服务质量(QoS)的研究和管理提供了一套通用术语.本建议书列出的与QoS相关的技术和非技术术语旨在代表电信市场所有各方(即用户.服务提供商.制造商和监管机构)的利益 ...
- 2010-01-20 12:09 ubuntu下minicom的安装及使用
转http://hi.baidu.com/npugtawqdnbgqrq/item/106f805409b42813db163527 ubuntu下minicom的安装及使用 安装: sudo apt ...
- 安卓TV开发(六) 移动智能终端UI之实现类似GridView的焦点控制FocusView框架
转载请标明出处:http://blog.csdn.net/sk719887916/article/details/40045089,作者:skay 前言 安卓TV开发(五) 移动智能终端UI之实现主流 ...
- 面试之路(16)-归并排序详解(MergeSort)递归和非递归实现
归并排序的概念及定义 归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立 ...
- 64位linux下安装ps模拟器ePSxe
早就想在爱机上玩ps游戏,特别是彩京的1945一代和非常经典的实况足球2002版.在ubuntu64位下可以通过wine模拟的方式运行windows版的ePSxe,但是总觉得差些呢?非原生啊!网上搜了 ...
- Java不走弯路教程(4.Client-Server模式(1)-Server)
4.Client-Server模式(1)-Server 在上一章中,我们完成了MyDataBase.java的编写,类似于一个简单的数据库功能,提供了用户验证,查询操作. 在本章中,我们将继续扩展这个 ...
- Fullpage参数说明
参数说明 $(document).ready(function() { $('#fullpage').fullpage({ //Navigation menu: false,//绑定菜单,设定的相关属 ...
- c语言 基本运算
计算机的基本能力就是计算,所以一门程序设计语言的计算能力是非常重要的.C语言之所以无所不能,是因为它不仅有丰富的数据类型,还有强大的计算能力.C语言一共有34种运算符,包括了常见的加减乘除运算.这讲就 ...