溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么用ASP.NET MVC源代碼尋找解決方案

發(fā)布時間:2021-10-28 10:17:25 來源:億速云 閱讀:98 作者:柒染 欄目:編程語言

怎么用ASP.NET MVC源代碼尋找解決方案,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

ASP.NET MVC源代碼來尋找解決方案,由于在Action方法中可以調(diào)用BeginXxx方法,我們在AsyncActionResult中只需保留Begin方法返回的IAsyncResult,以及另一個對于EndXxx方法的引用。在AsyncActionResult的ExecuteResult方法中將會保存這兩個對象,以便在AsyncMvcHandler的EndProcessRequest方法中重新獲取并使用。根據(jù)“慣例”,我們還需要定義一個擴(kuò)展方法,方便開發(fā)人員在Action方法中返回一個AsyncActionResult。具體實現(xiàn)非常容易,在這里就展示一下異步Action的編寫方式:

[AsyncAction]  publicActionResultAsyncAction(AsyncCallbackasyncCallback,objectasyncState)  {  SqlConnectionconn=newSqlConnection("...;AsynchronousProcessing=true");  SqlCommandcmd=newSqlCommand("WAITFORDELAY'00:00:03';",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;  }   publicControllerController{get;privateset;}  publicRequestContextRequestContext{get;privateset;}  publicIControllerFactoryControllerFactory{get;privateset;}  publicHttpContextContext{get;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方法中將保存當(dāng)前Context——這點很重要,HttpContext.Current是基于 CallContext的,一旦經(jīng)過一次異步回調(diào)HttpContext.Current就變成了null,我們必須重設(shè)。接著將接收到的 AsyncCallback和AsyncState保留,并使用框架中現(xiàn)成的Execute方法執(zhí)行控制器。當(dāng)Execute方法返回時一整個Action方法的調(diào)用流程已經(jīng)結(jié)束,這意味著其調(diào)用結(jié)果——即IAsyncResult和EndDelegate對象已經(jīng)保留。于是將IAsyncResult對象取出并返回。至于EndProcessRequest方法,只是將BeginProcessRequest方法中保存下來的EndDelegate取出,調(diào)用,把得到的ActionResult再執(zhí)行一遍即可。

以上的代碼只涉及到普通情況下的邏輯,而在完整的代碼中還會包括對于Action方法被某個Filter終止或替換等特殊情況下的處理。此外,無論在BeginProcessRequest還是EndProcessRequest中都需要對異常進(jìn)行合適地處理,使得Controller Factory能夠及時地對Controller對象進(jìn)行釋放。

如果這個解決方案沒有缺陷,那么相信它已經(jīng)被放入ASP.NET MVC 1.0中,而輪不到我在這里擴(kuò)展一番了。目前的這個解決方案至少有以下幾點不足:

沒有嚴(yán)格遵守.NET中的APM模式,雖然不影響功能,但這始終是一個遺憾。

由于利用了框架中的現(xiàn)成功能,所有的Filter只能運行在BeginXxx方法上。

由于EndXxx方法和最終ActionResult的執(zhí)行都沒有Filter支持,因此如果在這個過程中拋出了異常,將無法進(jìn)入ASP.NET MVC建議的異常處理功能中。

根據(jù)ASP.NET MVC框架的Roadmap,ASP.NET MVC框架1.0之后的版本中將會支持異步Action,相信以上這些缺陷到時候都能被彌補。不過這就需要大量的工作,這只能交給ASP.NET MVC團(tuán)隊去慢慢執(zhí)行了。事實上,您現(xiàn)在已經(jīng)可以在ASP.NET MVC源代碼的MvcFutures項目中找到異步Action處理的相關(guān)內(nèi)容。它添加了 IAsyncController,AsyncController,IAsyncActionInvoker,AsyncControllerActionInvoker 等許多擴(kuò)展。雖說它們都“繼承”了現(xiàn)有的類,但是與我之前的判斷相似,如AsyncControllerActionInvoker幾乎完全重新實現(xiàn)了一遍ActionInvoker中的各種功能——我還沒有仔細(xì)閱讀代碼,因此無法判斷出這種設(shè)計是否優(yōu)秀,只希望它能像ASP.NET MVC本身那樣的簡單和優(yōu)雅。

我打算為現(xiàn)在的代碼的EndXxx方法也加上Filter支持,我需要仔細(xì)閱讀ASP.NET MVC源代碼來尋找解決方案。希望它能夠成為ASP.NET MVC正式支持異步Action之前較好的替代方案。

關(guān)于怎么用ASP.NET MVC源代碼尋找解決方案問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI