概述ASP.NET MVC框架
创始人
2024-04-19 06:01:26
0

异步请求处理是ASP.NET 2.0中引入的高级特性,它依托IO Complete Port,对于提高IO密集型应用程序的吞吐量非常重要(详见原理描述和性能测试)。但是目前ASP.NET MVC框架缺少异步Action功能,这也就是老赵经常挂在嘴边的那个“目前ASP.NET MVC所缺少的非常重要的功能”。在TechED 2008 China的Session中我曾经给出过一个所谓的“解决方案”,但是它复杂性之高使那个解决方案有太多限制。

为了弥补TechED上的遗憾,以及准备.NET开发大会上的ASP.NET MVC***实践的Session,我在春节休假期间仔细思考了一下这方面的问题,得出了一个相对不错的扩展:完整,方便,并且非常轻巧——核心逻辑代码只有200行左右,这意味着绝大部分功能将会委托给框架中现成的内容,确保了扩展的稳定,高效并且拥有较好的向后兼容性。

值得一提的是,我在1/26号便基于ASP.NET MVC的Beta版本写出了这个扩展的***个版本,而在不久之后微软发布了ASP.NET MVC RC。我在移植解决方案的过程中发现ASP.NET MVC RC在框架设计上进行了较大的改进,这使得我在构建扩展时的策略发生了些许变化。令人欣喜的是,RC版本的这些变化对于构建一个扩展,尤其是现在这种“低端”级别的扩展变得更加容易。ASP.NET MVC框架实现了它“到处可扩展”的承诺。

那么我们现在就来详细分析一下这个扩展的实现方式。

请求处理方式的改变

在制定基本改造策略之前,我们需要了解ASP.NET MVC框架目前的架构及请求处理流程。如下:

在应用程序启动时(此时还没有接受任何请求),将针对MVC请求的Route策略注册至ASP.NET Routing模块。此时每个Route策略(即Route对象)中的RouteHandler属性为ASP.NET MVC框架中的MvcRouteHandler。

当ASP.NET Routing模块接收到一个匹配某个Route策略的HTTP请求时,将会调用该Route对象中RouteHandler对象的GetHttpHandler以获取一个HttpHandler,并交由ASP.NET执行。MvcRouteHandler永远将返回一个MvcHandler对象。

MvcHandler在执行时,将取出RouteData中的controller值,并以此构建一个实现了IController接口的控制器对象,并调用IController接口的Execute方法执行该控制器。

对于一个ASP.NET MVC应用程序来说,大部分控制器将会继承System.Web.Mvc.Controller类型。Controller类将会从RouteData获取action值,并交给实现IActionInvoker接口的对象来执行一个Action。
……

如果我们要将这个流程改造成异步处理,那么就要让它符合ASP.NET架构中的异步处理方式。ASP.NET架构对于异步请求的处理可以体现在好几种方式上,例如异步页面,异步Http Module等,而最适合目前场合的做法自然是异步Http Handler。为实现一个异步Handler,我们需要让处理请求的Handler实现IHttpAsyncHandler接口,而不是传统的 IHttpHandler接口。IHttpAsyncHandler接口中的BeginProcessRequest和 EndProcessRequest两个方法构成了.NET中的APM(Aynchronous Programming Model,异步编程模型)模式,可以使用“二段式”的异步调用来处理一个HTTP请求。

您应该已经发现,如果我们要支持异步Action,就必须根据当前的请求信息来确认究竟是执行一个IHttpHandler对象还是IHttpAsyncHandler对象。而在ASP.NET MVC框架在默认情况下是在Http Handler(即MvcHandler对象)内部进行控制器的检查,构造和调用。这为时已晚,我们必须讲这些逻辑提前到Routing过程中才行。幸运的是,ASP.NET Routing所支持的IRouteHandler就像是ASP.NET中的IHttpHandlerFactory,可以根据情况生成不同的Handler来执行。因此,我们只要构建一个新的IRouteHandler类型即可。于是就诞生了AsyncMvcRouteHandler——可以想象的出,其中的部分代码与框架中的MvcHandler相同,因为在一定程度上我们的确只是把原本在MvcHandler里做的事情给提前了:

 

  1. publicclassAsyncMvcRouteHandler:IRouteHandler  
  2. {  
  3. publicIHttpHandlerGetHttpHandler(RequestContextrequestContext)  
  4. {  
  5. stringcontrollerName=requestContext.RouteData.GetRequiredString("controller");  
  6.  
  7. varfactory=ControllerBuilder.Current.GetControllerFactory();  
  8. varcontroller=factory.CreateController(requestContext,controllerName);  
  9. if(controller==null)  
  10. {  
  11. thrownewInvalidOperationException(...);  
  12. }  
  13.  
  14. varcoreController=controllerasController;  
  15. if(coreController==null)  
  16. {  
  17. returnnewSyncMvcHandler(controller,factory,requestContext);  
  18. }  
  19. else  
  20. {  
  21.  
  22. stringactionName=requestContext.RouteData.GetRequiredString("action");  
  23. returnIsAsyncAction(coreController,actionName,requestContext)?  
  24. (IHttpHandler)newAsyncMvcHandler(coreController,factory,requestContext):  
  25. (IHttpHandler)newSyncMvcHandler(controller,factory,requestContext);  
  26. }  
  27. }  
  28.  
  29. internalstaticboolIsAsyncAction(  
  30. Controllercontroller,stringactionName,RequestContextrequestContext)  
  31. {  
  32. ...  
  33. }  

【编辑推荐】

  1. 介绍ASP.NET 2.0虚拟主机
  2. 浅谈ASP.NET应用程序
  3. 优化ASP.NET 2.0 Profile Provider
  4. 浅谈ASP.NET管道优化
  5. 介绍ASP.NET Routing引擎

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...