异步Action之AsyncController

1.为什么需要异步Action

  池的模式一直是我们处理对象频繁创建、销毁时采取的一种策略。就像一个大型图书馆,当我们需要某种图书的时候只需要到里面寻找就可以了,使用完毕之后放回;而不是每次想要获取的时候通知印刷厂为我们印刷一本。ASP.NET对HTTP的请求处理也是采用了线程池的方式,每个web应用内部都维护着一个线程池,当请求到达之后ASP.NET会从线程池中取出一个空闲的线程来专门处理这次请求,请求结束之后线程也不是被直接销毁而是放回到线程池供其他请求使用。需要注意的是线程池有一个最大容量如果请求数量超过这个容量ASP.NET会采取队列排队的方式对请求进行排队,这个时候我们就会感觉到网页的响应时间边长,就像图书馆里面只有10本书现在来了20个人想要借书那么我们就让多余的人进行排队。

  线程池的设计可以给我们带来以下优点

  · 线程重用:线程的创建和销毁同样需要占用服务器资源,采用线程池设计避免了频繁的创建和销毁进而提高服务器的吞吐能力(可以有更多的资源用于其他方面)

  · 最大数量限制:最大数量限制避免了创建过多线程导致的服务器崩溃现象  

  如果请求的处理过程很短,线程池内的线程在使用后会被很快的重新放回线程池,这当然是最理想的状态。但如果请求处理过程很长(比如IO处理)那么就会导致线程不能被快速使用完毕后放回至线程池,影响服务器吞吐能力。异步即为了解决这一问题,我们可以在线程池里的线程在使用时如果遇到耗时操作(主要针对IO)为其创建一个后台线程专门处理耗时操作,从而让线程池中的线程可以尽快返还到线程池中提高服务器吞吐能力。

2.异步Action定义

  在mvc3的版本中提供了定义异步Action的一种方式,即创建XxxAsync()方法和XxxCompleted()两个方法,XxxCompleted()方法是XxxAsync()方法执行完毕之后的回调方法。ASP.NET并不会以异步的方式执行XxxAsync()方法,而是我们在XxxAsync()方法内自行实现异步。MVC4以后的版本我们可以使用Task完成异步操作。

 1     public class HomeController : AsyncController
 2     {
 3
 4         public void IndexAsync()
 5         {
 6             //异步执行开始标志
 7             AsyncManager.OutstandingOperations.Increment();
 8             Task.Factory.StartNew(() =>
 9             {
10                 string path = ControllerContext.HttpContext.Server.MapPath("\\Texts\\围城.txt");
11                 using (StreamReader sr = new StreamReader(path))
12                 {
13                     //回调时传递的参数
14                     AsyncManager.Parameters["Content"] = sr.ReadToEnd();
15                 }
16                 AsyncManager.Parameters["count"] = 1;
17                 AsyncManager.Parameters["person"] = new Person { Name = "张三" };
18                 //异步执行结束标志 ①
19                 AsyncManager.OutstandingOperations.Decrement();
20             });
21             //②
22
23         }
24
25         public ActionResult IndexCompleted(string content, int count,Person person)
26         {
27             return Content(content);
28         }
29
30     }
31
32     public class Person
33     {
34         public string Name { set; get; }
35     }

AsyncController

  跟踪执行过程

  此种方式操作起来相对比较麻烦。而且一般需要借助于AcynManager对象完成异步操作。

3.AsyncManager

  首先我们把代码中标注①的代码放到//②的位置,再跟踪代码会发现IndexCompleted(string content, int count,Person person)方法中的参数有时会被赋值有时为null,

这又是为什么呢?

  AsyncManager.OutstandingOperations.Decrement();标志后台线程执行完毕,此时可以开始执行IndexCompleted方法,如果把它放到②位置处则只是通知IndexAsync方法执行完毕,至于Task.Factory.StartNew中的后台任务不一定执行完毕,所以出现上述情况,因此使用此种方式设计一部Action时我们需要注意AsyncManager.OutstandingOperations.Decrement();的位置。

  下面我们深入分析一下AsyncManager的原理

时间: 2024-10-11 00:11:13

异步Action之AsyncController的相关文章

ASP.NET MVC下的异步Action的定义和执行原理

Visual Studio提供的Controller创建向导默认为我们创建一个继承自抽象类Controller的Controller类型,这样的Controller只能定义同步Action方法.如果我们需要定义异步Action方法,必须继承抽象类AsyncController.这篇问你讲述两种不同的异步Action的定义方法和底层执行原理.[本文已经同步到<How ASP.NET MVC Works?>中] 目录 一.基于线程池的请求处理 二.两种异步Action方法的定义     XxxAs

ASP.NET MVC下的异步Action的定义和执行原理[转]

http://www.cnblogs.com/artech/archive/2012/06/20/async-action-in-mvc.html Visual Studio提供的Controller创建向导默认为我们创建一个继承自抽象类Controller的Controller类型,这样的Controller只能定义同步Action方法.如果我们需要定义异步Action方法,必须继承抽象类AsyncController.这篇问你讲述两种不同的异步Action的定义方法和底层执行原理.[本文已经

ASP.NET MVC什么时候使用异步Action

在没有使用异步Action之前,在Action内,比如有如下的写法: public ActionResult Index() { CustomerHelper cHelper = new CustomerHelper(); List<Customer> result = cHelper.GetCustomerData(); return View(result); } 以上,假设,GetCustomerData方法是调用第三方的服务,整个过程都是同步的,大致是: →请求来到Index这个Act

redux学习日志:关于异步action

当我们在执行某个动作的时候,会直接dispatch(action),此时state会立即更新,但是如果这个动作是个异步的呢,我们要等结果出来了才能知道要更新什么样的state(比如ajax请求),那就没办法了,所以此时要用异步action. 这里一定要引入redux-thunk这个库,通过使用中间件Middleware来把从action到reducer这个过程给拆分成很多个小过程,这样我们就能在中间随时查找此刻的状态以及执行一些其他动作了.具体的Middleware和redux-thunk以后再

异步action和redux-thunk理解

异步action一般指的就是异步action创建函数 action创建函数分为同步action创建函数和异步action创建函数 同步action创建函数(最常见的): function requestPosts(subreddit) { return { type: REQUEST_POSTS, subreddit } } 异步action创建函数(如果利用了redux-thunk,也叫thunk action创建函数,通过使用指定的 middleware,action 创建函数除了返回 ac

夜深了 关于 异步Action的定义的截图

Action的执行

异步Action的定义 两种异步Action方法的定义 xxxAsync/xxxCompleted 这种形式的异步只能定义在实现了AsyncController的Controller中.针对Task的异步没有这个限制 可以将异步操作实现在X xxAsync 方法中,而将最终内容的响应实现在XxxCompleted 方法中 对于以XxxA synclXxxCompleted 形式定义的异步Action 方法来说, ASP.NET MVC 并不会以异步的方式来调用XxxAsync 方法,所以我们需要

ASP.NET MVC 4 异步加载控制器

ASP.NET 4 Developer preview中的异步操纵器 在放弃了对.NET 3的支持之后, ASP.NET MVC 4 彻底拥抱了Task类库, 你不需求再蛋疼的给每个Action写两个方法, 也无需傻傻的手动对异步Action计数器增减了(AsyncManager.OutstandingOperations.Increment()), 现在的你只需拿起手指, 轻轻敲几下, 其他的事情都由系统帮你完成. public class PortalController : AsyncCo

ASP.NET异步处理

前一篇:详解 .NET 异步 在前文中,介绍了.NET下的多种异步的形式,在WEB程序中,天生就是多线程的,因此使用异步应该更为谨慎.本文将着重展开ASP.NET中的异步. [注意]本文中提到的异步指的是服务器端异步,而非客户端异步(Ajax). 对于HTTP的请求响应模型,服务器无法主动通知或回调客户端,当客户端发起一个请求后,必须保持连接等待服务器的返回结果,才能继续处理,因此,对于客户端来说,请求与响应是无法异步进行,也就是说无论服务器如何处理请求,对于客户端来说没有任何差别. 那么ASP