Visual Studio提供的Controller创建向导默认为我们创建一个继承自抽象类Controller的Controller类型,这样的Controller只能定义同步Action方法。如果我们需要定义异步Action方法,必须继承抽象类AsyncController。这篇问你讲述两种不同的异步Action的定义方法和底层执行原理。
一、基于线程池的请求处理
ASP.NET通过线程池的机制处理并发的HTTP请求。一个Web应用内部维护着一个线程池,当探测到抵达的针对本应用的请求时,会从池中获取一个空闲的线程来处理该请求。当处理完毕,线程不会被回收,而是重新释放到池中。线程池具有一个线程的最大容量,如果创建的线程达到这个上限并且所有的线程均被处于“忙碌”状态,新的HTTP请求会被放入一个请求队列以等待某个完成了请求处理任务的线程重新释放到池中。
我们将这些用于处理HTTP请求的线程称为工作线程(Worker Thread),而这个县城池自然就叫做工作线程池。ASP.NET这种基于线程池的请求处理机制主要具有如下两个优势:
如果请求处理操作耗时较短,那么工作线程处理完毕后可以及时地被释放到线程池中以用于对下一个请求的处理。但是对于比较耗时的操作来说,意味着工作线程将被长时间被某个请求独占,如果这样的操作访问比较频繁,在高并发的情况下意味着线程池中将可能找不到空闲的工作线程用于及时处理最新抵达请求。
如果我们采用异步的方式来处理这样的耗时请求,工作线程可以让后台线程来接手,自己可以及时地被释放到线程池中用于进行后续请求的处理,从而提高了整个服务器的吞吐能力。值得一提的是,异步操作主要用于I/O绑定操作(比如数据库访问和远程服务调用等),而非CPU绑定操作,因为异步操作对整体性能的提升来源于:当I/O设备在处理某个任务的时候,CPU可以释放出来处理另一个任务。如果耗时操作主要依赖于本机CPU的运算,采用异步方法反而会因为线程调度和线程上下文的切换而影响整体的性能。
新闻热点
疑难解答
图片精选