Asp.net MVC Action同步异步执行
Web开发新手一直有个很困惑的问题?Web开发需要异步开发吗?答案时肯定的,原因细细道来。
Web客户端(浏览器)发送Http请求 -----> IIS服务器接受请求------>调用Asp.net,Asp.net为每个请求新建一个请求线程(通过一个线程池维护),因Asp.net请求线程所占资源比较大(一般请求线程是个确定值),那么在客户端请求量超过“请求线程”数量,“请求”将放入等待队列,等线程池中有空闲线程调用。所以因使用异步,在一些(IO操作、数据库读取、网络请求)时不要阻塞“请求线程”。
Asp.net MVC中的异步
HttpHandler异步
MvcHandler
为Asp.net中处理处理呈现,实现了IHttpHandler
和IHttpAsyncHandler
。Asp.net MVC总是按异步IHttpAsyncHandler
执行。异步方法BeginProcessRequest
和EndProcessRequest
。
Controller执行的异步
Controller
是通过ControllerFactory
和ControllerName
得到Controller
实体。但是关于Controller
的执行分为同步和异步,分别实现IController
和IAsyncController
。其中Controller
同时实现了同步和异步,默认是按照异步执行的,可以重写DisableAsyncSupport
。这里正则执行的是BeginExecuteCore
和EndExecuteCore
分别存入委托。
注意 AsyncController
与Controller
同步异步没关系,而是用于AMP
的ActionInvoker
的标记。
ActionInvoker异步
Controller
中的Action
最终是封装到ActionInvoker
执行的,关于Action
的异步调用是最复杂的,是通过一套组件设置的。
首先关于IActionInvoker
有同步有ControllerActionInvoker
实现(如果通过ControllerActionInvoker
则Action
是为同步调用),IAsyncActionInvoker
有AsyncControllerActionInvoker
实现。在没有注入时,默认为AsyncControllerActionInvoker
(通过Controller.CreateActionInvoker()
的方法得到)。
这里得到了ActionInvoker
异步模式,但是执行Action
需要封装在ActionDecriptor
下,而需要现货的ContollerDescriptor
。通过ActionInvoker.GetControllerDescriptor()
方法获得。
最终通过ActionDecriptor.Execute
执行Action
调用
接下来先大概接受下Asp.net MVC执行流程,在介绍下两种异步执行Action的方式。
同步执行
- 这里从
MvcHandler
处理呈现开始,通过IControllerFactory
的到Controller
- 执行
Controller
,调用Execute
,将Controller
实体和ActionName
传入IActionInvoker
ActionInvoker
最终执行Action
- 权限过滤
Filter
- 得到
ControllerDescriptor
/ActionDescriptor
/ParameterDescriptor
- 执行数据绑定和数据验证
- 通过
actionDescriptor.Execute(controllerContext, parameters)
执行Action
返回ActionResult
- 得到
ActionExecutedContext
(其Result
为Action
返回值)。供View
使用
- 权限过滤
AMP异步模式
异步实现要求
- 定义的
Controller
继承AsyncController
(一个空类只为标记)抽象了 - 将一个
Action
拆分为两个方法XXXAsync
/XXXCompleted
注意XXXCompleted
是回调方法,XXXAsync
中函数中有异步操作需要AsyncManager
内部异步执行流程 Controller.CreateActionInvoker()
得到AsyncControllerActionInvoker
AsyncControllerActionInvoker.GetControllerDescriptor()
得到ReflectedAsyncControllerDescriptor
AsyncControllerActionInvoker.FindAction()
得到ReflectedAsyncActionDescriptor
Task异步模式
返回类型为Task<>
内部异步执行流程
Controller.CreateActionInvoker()
得到AsyncControllerActionInvoker
AsyncControllerActionInvoker.GetControllerDescriptor()
得到ReflectedAsyncControllerDescriptor
AsyncControllerActionInvoker.FindAction()
得到TaskAsyncActionDescriptor