快速业务通道

为ASP.NET MVC扩展异步Action功能

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-20
xt)   {     this.Controller = controller;     this.ControllerFactory = controllerFactory;     this.RequestContext = requestContext;   }   public IController Controller { get; private set; }   public RequestContext RequestContext { get; private set; }   public IControllerFactory ControllerFactory { get; private set; }   public virtual bool IsReusable { get { return false; } }   public virtual void ProcessRequest(HttpContext context)   {     try     {       this.Controller.Execute(this.RequestContext);     }     finally     {       this.ControllerFactory.ReleaseController(this.Controller);     }   } }

而对于异步Action,我之前一直思考着怎么将框架的默认实现,也就是单个方法调用,转化成两个方 法(BeginXxx/EndXxx)调用。曾经我想过自己实现一个新的ActionInvoker,但是这就涉及到了大量的工 作,尤其是如果希望保持框架现有的功能(ActionFilter,ActionSelector等等),最省力的方法可能就 是继承ControllerActionInvoker,并设法使用框架已经实现的各种辅助方法。但是在分析了框架代码之 后我发现复用也非常困难,举例来说,ControllerActionInvoker判定一个方法为Action的依据之一是这 个方法返回的是ActionResult类型或其子类,这意味着我无法直接使用这个方法来获取一个返回 IAsyncResult的BeginXxx方法;同理,对于查找EndXxx方法,我可能需要在请求名为Abc的异步Action时 ,将EndAbc作为查找依据交由现成的方法来查询——但是,如果又有一个请求是直接针对一个名为EndAbc 的同步Action的那又怎么办呢?

由于这些问题存在,我在去年设法实现异步Action时几乎重写了整个ActionInvoker——其复杂程度可 见一斑。而且那个实现对于一些特殊情况的处理依旧不甚友好,需要开发人员在一定程度上做出妥协。这 个实现在TechED 2008 China的Session中公布时我就承认它并不能让我满意,建议大家不要将其投入生产 环境中。而现在的实现,则非常顺利地解决了整个问题。虽然从理论上讲还不够“完美”,虽然还做出了 一些让步。

带来如此多问题的原因就在于我们在设法颠覆框架内部的关键性设计,也就是从单一的Action方法调 用,转变为“符合APM的”二段式调用。等等,您是否感觉到了解决问题的关键?没错,那就是“符合APM 的”。APM要求我们将一个行为分为BeginXxx和EndXxx两个方法,可是既然ASP.NET MVC框架只能让我们返 回一个ActionResult对象……那么我们为什么不在这个对象里包含方法的引用——也就是一个委托对象呢 ?这虽然不符合正统的APM签名,但是完全可行,不是吗?

public class AsyncActionResult : ActionResult
{
  public AsyncActionResult(
    IAsyncResult asyncResult,
    Func<IAsyncResult, ActionResult> endDelegate)
  {
    this.AsyncResult = asyncResult;
    this.EndDelegate = endDelegate;
  }
  public IAsyncResult AsyncResult { get; private set; }
  public Func<IAsyncResult, ActionResult> EndDelegate { get; private set; }
  public override void ExecuteResult(ControllerContext context)
  {
    context.Controller
      .SetAsyncResult(this.AsyncResult)
      .SetAsyncEndDelegate(this.EndDelegate);
  }
}

由于在Action方法中可以调用BeginXxx方法,我们在AsyncActionResult中只需保留Begin方法返

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号