1. 程式人生 > >使用ASP.NET MVC Futures 中的非同步Action

使用ASP.NET MVC Futures 中的非同步Action

之前看過老趙這兩篇文章。也研究了一下老趙非同步的實現方式。

不過感覺自己擴充套件的話,在ASP.NET MVC中使用非同步還真是麻煩,剛好看到從RC1版開始 ASP.NET MVC Futures中提供了幾個支援非同步的類。

相關的類包括AsyncActionDescriptor、AsyncController、AsyncControllerActionInvoker、AsyncManager、AsyncResultWrapper、AsyncTimeoutAttribute、NoAsyncTimeoutAttribute,相關介面有IAsyncActionDescriptor、IAsyncActionInvoker、IAsyncController、IAsyncManagerContainer。

下面說一下怎麼用它們

一、使用非同步Action前的準備工作

1.引用Microsoft.Web.Mvc。    

2.先要將要非同步處理的Url交由MvcHttpAsyncHandler處理,這一步可以由AsyncRouteCollectionExtensions.MapAsyncRoute來設定規則,將原MapRoute處理的規則改為MapAsyncRoute,如:

            routes.MapAsyncRoute(
                "Default",
                "{controller}/{action}/{id}",
                new
{ controller = "Home", action = "Index", id = "" } );

3.將相應的Controller繼承於AsyncController。

    public class HomeController : AsyncController    {    }

4.我們約定以下定義的Action都在HomeController中

二、第一種非同步Action方式:Action、ActionCompleted方式

ASP.NET MVC Futures支援按名稱自動尋找非同步Action的方法

其使用方法為

       public
void Async1(){ //主執行緒 } public ActionResult Async1Completed(){ //自動尋找與主執行緒 Action名稱+Completed 的Action 做為非同步Action return Content("Async1"); }

三、第二種非同步Action方式:BeginAction、EndAction方式

如果第一種方式你瞭解了的話第二種自然也不在話下,不過這種方式是與其它類的非同步呼叫一起使用。

        public delegate void AsyncEventHandler();//我這裡自己聲明瞭一個委託,也可以使用WebRequest/WebResponse/SqlConnection來實現這個非同步過程
        public void Event1(){}
        public IAsyncResult BeginAsync3(AsyncCallback callback, object state){
           AsyncEventHandler asy = new AsyncEventHandler(Event1);
            ViewData["a"]=asy;//這裡在方法間傳值必須使用輔助儲存物件,第一種方法中也是一樣
            return asy.BeginInvoke(callback, state);
        }
        public void EndAsync3(IAsyncResult result){
//轉到非同步的Action中
            var a = ViewData["a"] as AsyncEventHandler;
            a.EndInvoke(result);
            Content("完成").ExecuteResult(this.ControllerContext);
        }

四、第三種非同步Action方式:使用AsyncManager.RegisterTask及委託

如果感覺上面使用2個方法才能實現非同步Action有些麻煩的話(也的確是麻煩),可以使用AsyncManager.RegisterTask來呼叫委託來實現非同步呼叫。

  	public void  Async2(){
            this.AsyncManager.RegisterTask(c => {
                //主執行緒,呼叫非同步執行緒
                c(null);
            }, delegate(IAsyncResult result) {
                //非同步部分               
                Content("Async2").ExecuteResult(this.ControllerContext);
            });
        }

其實無論是哪種方法都感覺不太完美,我個人覺得Action/ActionCompleted的方法可能更優美一點,適合一般使用(只是這三個比較)。只是AsyncManager.RegisterTask的方法傳值方便一點,而Begin/End方法更適合與其它非同步的操作配合。

當然本文還有肯定還有好多地方沒有講到,包括其它的非同步呼叫方式還有Filter,所以希望朋友們多多討論。

附老趙2個文章