池的模式一直是咱们处理对象频繁建立、销毁时采起的一种策略。就像一个大型图书馆,当咱们须要某种图书的时候只须要到里面寻找就能够了,使用完毕以后放回;而不是每次想要获取的时候通知印刷厂为咱们印刷一本。ASP.NET对HTTP的请求处理也是采用了线程池的方式,每一个web应用内部都维护着一个线程池,当请求到达以后ASP.NET会从线程池中取出一个空闲的线程来专门处理此次请求,请求结束以后线程也不是被直接销毁而是放回到线程池供其余请求使用。须要注意的是线程池有一个最大容量若是请求数量超过这个容量ASP.NET会采起队列排队的方式对请求进行排队,这个时候咱们就会感受到网页的响应时间边长,就像图书馆里面只有10本书如今来了20我的想要借书那么咱们就让多余的人进行排队。web
线程池的设计能够给咱们带来如下优势服务器
· 线程重用:线程的建立和销毁一样须要占用服务器资源,采用线程池设计避免了频繁的建立和销毁进而提升服务器的吞吐能力(能够有更多的资源用于其余方面)多线程
· 最大数量限制:最大数量限制避免了建立过多线程致使的服务器崩溃现象 mvc
若是请求的处理过程很短,线程池内的线程在使用后会被很快的从新放回线程池,这固然是最理想的状态。但若是请求处理过程很长(好比IO处理)那么就会致使线程不能被快速使用完毕后放回至线程池,影响服务器吞吐能力。异步即为了解决这一问题,咱们能够在线程池里的线程在使用时若是遇到耗时操做(主要针对IO)为其建立一个后台线程专门处理耗时操做,从而让线程池中的线程能够尽快返还到线程池中提升服务器吞吐能力。异步
在mvc3的版本中提供了定义异步Action的一种方式,即建立XxxAsync()方法和XxxCompleted()两个方法,XxxCompleted()方法是XxxAsync()方法执行完毕以后的回调方法。ASP.NET并不会以异步的方式执行XxxAsync()方法,而是咱们在XxxAsync()方法内自行实现异步。MVC4之后的版本咱们可使用Task完成异步操做。ide
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 }
跟踪执行过程spa
此种方式操做起来相对比较麻烦。并且通常须要借助于AcynManager对象完成异步操做。线程
首先咱们把代码中标注①的代码放到//②的位置,再跟踪代码会发现IndexCompleted(string content, int count,Person person)方法中的参数有时会被赋值有时为null,设计
这又是为何呢?code
AsyncManager.OutstandingOperations.Decrement();标志后台线程执行完毕,此时能够开始执行IndexCompleted方法,若是把它放到②位置处则只是通知IndexAsync方法执行完毕,至于Task.Factory.StartNew中的后台任务不必定执行完毕,因此出现上述状况,所以使用此种方式设计一部Action时咱们须要注意AsyncManager.OutstandingOperations.Decrement();的位置。