1)         异步控制器的由来

  对于IIS,它维护了一个.NET线程池来处理客户端请求,这个线程池称为工作线程池,其中的线程称为工作线程。当IIS接收到一个请求时,需要从工作线程池中唤醒一个工作线程,并处理请求,处理完成后,工程线程再被线程池回收。使用线程池回收机制,通过线程的重复使用,避免了每次接受请求都创建一个新的线程,从而避免了服务器发生崩溃的风险。

  绝大部分情况下,请求的执行过程都是非常快的。但是在个别情况可能会调用耗时操作(比如,读取文件或调用其他服务),造成工作线程耗用大量时间,这种情况下,线程池可能会没有多余的资源可用,从而发生Thread Starvation线程。当出现这种问题时,后续的客户端请求将会被放入队列,直到有工作线程被释放,但是,当队列也达到一定的数目时,就不会再接受新的请求,直接返回503错误码(服务器忙碌)。

2)         异步控制器的工作步骤

  为了避免出现上述问题,可以使用异步控制器方式来操作耗时比较长的操作,它的工作步骤如下:

  ASP.NET从线程池获取工作线程来处理请求,异步调用完ASP.NET MVC 操作后,它将工作线程返还给线程池以便处理其他的情况,异步操作在其他线程上执行完成后,通过ASP.NET已完成,然后从线程池获取一个工作线程,调用这个线程处理请求的返回。

3)         异步控制器的创建

  平常使用的控制器都是从Controller中派生出来,而异步控制器需要从AsynController派生出来,这个基类提供了异步处理请求的帮助方法。

在ASP.NET MVC4框架之前,遵守下面的开发契约来创建异步控制器的方法,

操作名称Async:

此方法必须返回void,它会开始异步处理过程。

操作名称Completed:

此方法会在异步处理完成后调用,它的返回结果是ActionResult。

 public class TestController:AsynController
{
public void TestAsync()
{
AsyncManager.OutstandingOperations.Increment();
var worker = new BackgroundWorker();
worker.DoWork +=(o,e)=>TestMethod(e);
worker.RunWorkerCompleted+=(o,e)=>{
AsyncManager.Parameters["ReturnData"]=e.Result;
AsyncManager.OutstandingOperations.Decrement();
};
worker.RunWorkerAsync();
} public void TestMethod(DoWorkEventArgs e)
{
//处理过程
e.Result=returnData;
} public ActionResult TestCompleted(returnData)
{
return Json(returnData,JsonRequestBehavior.AllowGet); }
}

Ps:AsyncManager.OutstandingOperations在操作开始前+1,操作完成后减1。它的作用就是通过ASP.NET 框架目前有多少个等待操作,当属性OutstandingOperations为0时,ASP.NET会完成所有的异步请求方法,并且调用XXXCompleted方法。

.Net Framework4.5引入了新的关键字async和await后简化了异步编程模型。上述代码就可以调整为:

 public class TestController:AsynController
{
public async Tash<ActionResult> TestMethod()
{
var returnData = await TestMethod();
return Json(returnData,JsonRequestBehavior.AllowGet);
} public async Task<Data> TestMethod()
{
//耗时操作
return returnData;
}
}

ASP.NET MVC 学习笔记-6.异步控制器的更多相关文章

  1. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  2. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  3. ASP.NET MVC学习笔记-----Filter2

    ASP.NET MVC学习笔记-----Filter(2) 接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用 ...

  4. ASP.NET MVC学习笔记-----Filter

    ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...

  5. ASP.NET MVC学习笔记-----Filter(2)

    接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用,它需要实现IActionFilter接口: public ...

  6. ASP.NET MVC EF 中使用异步控制器

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精   为什么使用异步操作/线程池 ASP.NET MVC ...

  7. ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用

    Ajax的全名为:Asynchronous Javascript And XML(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术.Ajax技术首先向Web服务器发送 ...

  8. ASP.NET MVC学习笔记-----使用自定义的View Engine

    我们都知道在ASP.NET MVC中自带了Razor View Engine,Razor十分的强大,可以满足我们绝大部分的需要.但是ASP.NET MVC的高度可扩展性,使我们可以使用自定义的View ...

  9. ASP.NET MVC 学习笔记(1)

    从头开始系统地学习ASP.NET MVC 为什么要学习ASP.NET MVC?原因很多,可以先来看一下最早的ASP.NET WebForm的一些缺点: 传说中面试经常要问到的ASP.NET WebFo ...

随机推荐

  1. java holdsLock()方法检测一个线程是否拥有锁

    http://blog.csdn.net/w410589502/article/details/54949506 java.lang.Thread中有一个方法叫holdsLock(),它返回true如 ...

  2. HTML5元素标记释义

    HTML5元素标记释义 标记 类型 意义 介绍 文件标记 <html> ● 根文件标记 让浏览器知道这是HTML 文件 META标记 <head> ● 开头 提供文件整体信息 ...

  3. 腾讯技术分享:微信小程序音视频技术背后的故事

    1.引言 微信小程序自2017年1月9日正式对外公布以来,越来越受到关注和重视,小程序上的各种技术体验也越来越丰富.而音视频作为高速移动网络时代下增长最快的应用形式之一,在微信小程序中也当然不能错过. ...

  4. 没执行过 rm -rf /* 的开发不是好运维

    阅读本文大概需要 1 分钟. 打开终端,获取 root 权限,执行以下命令:rm -rf /*,会发生什么呢?估计只要接触过 Linux 的人,肯定没少听过它的故事,清楚之后会发生什么可怕的事情. 科 ...

  5. python Event_loop(事件循环)

    由于GIL全局解释器锁的存在,意味着在任何一个时刻,只有一个线程处于执行状态. (1)执行栈: 因为python是单线程的,同一时间只能执行一个方法,所以当一系列的方法被依次调用的时候,python会 ...

  6. php 中构造函数和析构函数

    构造函数: 在对象实例化时被调用,一个类中只能有一个构造函数,在类中起初始化的作用. 析构函数: 在对象结束时被自动调用. 话不多说,用一段代码来说明两者的区别: <?php //定义一个类 c ...

  7. RIPng配置(第十三组)

    拓扑如下 配置rip指令和ipv6包允许路由指令以r1为例 在r1上配置拓扑上对应网段的ip,r1上两个连接路由器的端口手动设置ip,同网段的路由器端口ip自动获取. r2配置 r3 配置完后查看路由 ...

  8. Android获取手机号码

    今天来说一下Android系统中怎么获取手机号 一.SIM卡存储的数据可分为四类,它们分别是: 第一类是固定存放的数据.这类数据在移动电话机被出售之前由SIM卡中心写入,包括国际移动用户识别号(IMS ...

  9. React Native IOS搭建开发环境

    安装 必须的软件 Homebrew ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/mast ...

  10. 关于sql和MySQL的语句执行顺序(必看!!!)

    今天遇到一个问题就是mysql中insert into 和update以及delete语句中能使用as别名吗?目前还在查看,但是在查阅资料时发现了一些有益的知识,给大家分享一下,就是关于sql以及My ...