知识大全 用ASP.NET MVC源代码寻找解决方案
Posted 知
篇首语:与其降低你的开支,不如去尝试增加你的收入。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 用ASP.NET MVC源代码寻找解决方案相关的知识,希望对你有一定的参考价值。
用ASP.NET MVC源代码寻找解决方案 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
ASP NET MVC源代码来寻找解决方案 由于在Action方法中可以调用BeginXxx方法 我们在AsyncActionResult中只需保留Begin方法返回的IAsyncResult 以及另一个对于EndXxx方法的引用 在AsyncActionResult的ExecuteResult方法中将会保存这两个对象 以便在AsyncMvcHandler的EndProcessRequest方法中重新获取并使用 根据 惯例 我们还需要定义一个扩展方法 方便开发人员在Action方法中返回一个AsyncActionResult 具体实现非常容易 在这里就展示一下异步Action的编写方式
[AsyncAction]
publicActionResultAsyncAction(AsyncCallbackasyncCallback objectasyncState)
SqlConnectionconn=newSqlConnection( ;AsynchronousProcessing=true );
SqlCommandcmd=newSqlCommand( WAITFORDELAY : : ; conn); conn Open();
returnthis Async( cmd BeginExecuteNonQuery(asyncCallback asyncState) (ar)=>
intvalue=cmd EndExecuteNonQuery(ar);
conn Close();
returnthis View();
);
至此 似乎AsyncMvcHandler也无甚秘密可言了
publicclassAsyncMvcHandler:IHttpAsyncHandler IRequiresSessionState
publicAsyncMvcHandler( Controllercontroller IControllerFactorycontrollerFactory RequestContextrequestContext)
this Controller=controller;
this ControllerFactory=controllerFactory;
this RequestContext=requestContext;
publicControllerControllerget;privateset;
publicRequestContextRequestContextget;privateset;
publicIControllerFactoryControllerFactory
get;privateset;
publicHttpContextContextget;privateset;
publicIAsyncResultBeginProcessRequest( HttpContextcontext AsyncCallbackcb objectextraData)
this Context=context;
this Controller SetAsyncCallback(cb) SetAsyncState(extraData);
try
(this ControllerasIController) Execute(this RequestContext);
returnthis Controller GetAsyncResult();
catch
this ControllerFactory ReleaseController(this Controller);
throw;
publicvoidEndProcessRequest(IAsyncResultresult)
try
HttpContext Current=this Context;
ActionResultactionResult=this Controller GetAsyncEndDelegate()(result);
if(actionResult!=null)
actionResult ExecuteResult(this Controller ControllerContext);
finally
this ControllerFactory ReleaseController(this Controller);
在BeginProcessRequest方法中将保存当前Context——这点很重要 HttpContext Current是基于 CallContext的 一旦经过一次异步回调HttpContext Current就变成了null 我们必须重设 接着将接收到的 AsyncCallback和AsyncState保留 并使用框架中现成的Execute方法执行控制器 当Execute方法返回时一整个Action方法的调用流程已经结束 这意味着其调用结果——即IAsyncResult和EndDelegate对象已经保留 于是将IAsyncResult对象取出并返回 至于EndProcessRequest方法 只是将BeginProcessRequest方法中保存下来的EndDelegate取出 调用 把得到的ActionResult再执行一遍即可
以上的代码只涉及到普通情况下的逻辑 而在完整的代码中还会包括对于Action方法被某个Filter终止或替换等特殊情况下的处理 此外 无论在BeginProcessRequest还是EndProcessRequest中都需要对异常进行合适地处理 使得Controller Factory能够及时地对Controller对象进行释放
如果这个解决方案没有缺陷 那么相信它已经被放入ASP NET MVC 中 而轮不到我在这里扩展一番了 目前的这个解决方案至少有以下几点不足
没有严格遵守 NET中的APM模式 虽然不影响功能 但这始终是一个遗憾
由于利用了框架中的现成功能 所有的Filter只能运行在BeginXxx方法上
由于EndXxx方法和最终ActionResult的执行都没有Filter支持 因此如果在这个过程中抛出了异常 将无法进入ASP NET MVC建议的异常处理功能中
根据ASP NET MVC框架的Roadmap ASP NET MVC框架 之后的版本中将会支持异步Action 相信以上这些缺陷到时候都能被弥补 不过这就需要大量的工作 这只能交给ASP NET MVC团队去慢慢执行了 事实上 您现在已经可以在ASP NET MVC源代码的MvcFutures项目中找到异步Action处理的相关内容 它添加了 IAsyncController AsyncController IAsyncActionInvoker AsyncControllerActionInvoker 等许多扩展 虽说它们都 继承 了现有的类 但是与我之前的判断相似 如AsyncControllerActionInvoker几乎完全重新实现了一遍ActionInvoker中的各种功能——我还没有仔细阅读代码 因此无法判断出这种设计是否优秀 只希望它能像ASP NET MVC本身那样的简单和优雅
cha138/Article/program/net/201311/12912相关参考