前进中的蜗牛

番茄大叔

水滴穿石,非一日之功;没有量变,何来质变。

Asp.net MVC Action同步异步执行

Web开发新手一直有个很困惑的问题?Web开发需要异步开发吗?答案时肯定的,原因细细道来。
Web客户端(浏览器)发送Http请求 -----> IIS服务器接受请求------>调用Asp.net,Asp.net为每个请求新建一个请求线程(通过一个线程池维护),因Asp.net请求线程所占资源比较大(一般请求线程是个确定值),那么在客户端请求量超过“请求线程”数量,“请求”将放入等待队列,等线程池中有空闲线程调用。所以因使用异步,在一些(IO操作、数据库读取、网络请求)时不要阻塞“请求线程”。

Asp.net MVC中的异步

HttpHandler异步

MvcHandler为Asp.net中处理处理呈现,实现了IHttpHandlerIHttpAsyncHandler。Asp.net MVC总是按异步IHttpAsyncHandler执行。异步方法BeginProcessRequestEndProcessRequest

Controller执行的异步

Controller是通过ControllerFactoryControllerName得到Controller实体。但是关于Controller的执行分为同步和异步,分别实现IControllerIAsyncController。其中Controller同时实现了同步和异步,默认是按照异步执行的,可以重写DisableAsyncSupport。这里正则执行的是BeginExecuteCoreEndExecuteCore分别存入委托。
注意 AsyncControllerController同步异步没关系,而是用于AMPActionInvoker的标记。

ActionInvoker异步

Controller中的Action最终是封装到ActionInvoker执行的,关于Action的异步调用是最复杂的,是通过一套组件设置的。
首先关于IActionInvoker有同步有ControllerActionInvoker实现(如果通过ControllerActionInvokerAction是为同步调用),IAsyncActionInvokerAsyncControllerActionInvoker实现。在没有注入时,默认为AsyncControllerActionInvoker(通过Controller.CreateActionInvoker()的方法得到)。
这里得到了ActionInvoker异步模式,但是执行Action需要封装在ActionDecriptor下,而需要现货的ContollerDescriptor。通过ActionInvoker.GetControllerDescriptor()方法获得。
最终通过ActionDecriptor.Execute执行Action调用

接下来先大概接受下Asp.net MVC执行流程,在介绍下两种异步执行Action的方式。

同步执行

  1. 这里从MvcHandler 处理呈现开始,通过IControllerFactory的到Controller
  2. 执行Controller,调用Execute,将Controller实体和ActionName传入IActionInvoker
  3. ActionInvoker最终执行Action
    • 权限过滤Filter
    • 得到ControllerDescriptor/ActionDescriptor/ParameterDescriptor
    • 执行数据绑定和数据验证
    • 通过actionDescriptor.Execute(controllerContext, parameters)执行Action返回ActionResult
    • 得到 ActionExecutedContext(其ResultAction返回值)。供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
posted @ 2018-09-03 16:37  LoveTomato  阅读(1848)  评论(0编辑  收藏  举报