使用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的方法

Url:/Home/Async1

其使用方法为

       public void Async1(){
            //主线程
        }
        public ActionResult Async1Completed(){
            //自动寻找与主线程 Action名称+Completed 的Action 做为异步Action
            return Content("Async1");
        }

三、第二种异步Action方式:BeginAction、EndAction方式

如果第一种方式你了解了的话第二种自然也不在话下,不过这种方式是与其它类的异步调用一起使用。

Url:/Home/Async2

        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来调用委托来实现异步调用。

Url:/Home/Async3

  	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个文章

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

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

我的ASP.NET MVC系列:Asp.net Mvc Framework 系列

1
0
(请您对文章做出评价)
« 上一篇:ASP.NET MVC RC 2 发布
» 下一篇:ASP.NET MVC 重点教程一周年版 第一回 安装,并使ASP.NET MVC页面运行起来
posted @ 2009-03-06 01:01 重典 阅读(6106) 评论(31)  编辑 收藏 网摘 所属分类: ASP.NET MVC

  回复  引用  查看    
#1楼2009-03-06 08:11 | 郁闷的翩翩      
沙发啊!我来坐啊!
  回复  引用  查看    
#2楼2009-03-06 08:25 | fighter      
楼主辛苦,收藏。
  回复  引用  查看    
#3楼2009-03-06 08:46 | Haozes      
还真不知道页面如何异步把数据给页面呢
  回复  引用  查看    
#4楼[楼主]2009-03-06 09:05 | 重典      
@郁闷的翩翩
PP早

  回复  引用  查看    
#5楼[楼主]2009-03-06 09:05 | 重典      
@fighter
谢谢

  回复  引用  查看    
#6楼[楼主]2009-03-06 09:05 | 重典      
@Haozes
异步中返回ActionResult是有些麻烦的

  回复  引用  查看    
#7楼2009-03-06 09:10 | Jeffrey Zhao      
我觉得还是透明的好,要程序员把MapRoute改成MapAsyncRoute……
  回复  引用  查看    
#8楼[楼主]2009-03-06 09:13 | 重典      
@Jeffrey Zhao
快枪赵又出现了。。。

其实改什么都是改,替换一下。。。卡卡就完事了

  回复  引用  查看    
#9楼2009-03-06 09:15 | Q.Lee.lulu      
典典你晚上都干嘛去啦?老三更半夜的来发文,你也要学老赵减肥么?
  回复  引用  查看    
#10楼[楼主]2009-03-06 09:18 | 重典      
@Q.Lee.lulu
。。。。。生物钟被老赵破坏了。。。

  回复  引用  查看    
#11楼2009-03-06 09:25 | 紫色永恒      
生物钟被非典破坏
  回复  引用  查看    
#12楼2009-03-06 10:36 | 郁闷的翩翩      
--引用--------------------------------------------------
Q.Lee.lulu: 典典你晚上都干嘛去啦?老三更半夜的来发文,你也要学老赵减肥么?
--------------------------------------------------------
叫你昨晚一起睡,你跑哪去了

  回复  引用    
#13楼2009-03-06 11:06 | kisskiki[未注册用户]
--引用--------------------------------------------------
郁闷的翩翩: --引用--------------------------------------------------
Q.Lee.lulu: 典典你晚上都干嘛去啦?老三更半夜的来发文,你也要学老赵减肥么?
--------------------------------------------------------
叫你昨晚一起睡,你跑哪去了
--------------------------------------------------------
惊愕的飘过。

  回复  引用  查看    
#14楼[楼主]2009-03-06 11:21 | 重典      
@郁闷的翩翩
@kisskiki
不要惊愕,翩翩是大胡子带花男。。。

  回复  引用    
#15楼2009-03-06 11:48 | HahahaX[未注册用户]
看来楼主是没有做过异步编程的, 却来谈异步Action....

说实在在国内谈异步编程实在就是扯谈.

程序员水平的低下, 搞个异步调试都能调试死人,

还不如直接让线程挂住不就好了.

只有做SOCKET服务器或者是云HTTP才需要异步.

  回复  引用  查看    
#16楼2009-03-06 12:34 | Q.Lee.lulu      
@郁闷的翩翩
不和有女人的大胡子带花男睡,哇哈哈

  回复  引用  查看    
#17楼[楼主]2009-03-06 13:15 | 重典      
@HahahaX
我在ASP.NET MVC中没有明显看到异步带来的好处,但也尽可能在现有项目中执行时间较长的Action中使用,以窥探其但对程序效率的改变,

我之前在进行数据库操作和读写文件时还是用过不少的,比如在线实时编译的Online Judge系统,如果不异步,主线程根本无法同时处理哪怕是三五个人的同时提交。

我这篇文章也并未给出任何观点,只是陈述一下ASP.NET MVC中的一些新特性,我想不会

异步调试的确是很闹人,但是也不是无计可施
我相信调试到无错,这个一般水平的程序员,只要有足够耐心是可以做到的

对于只有对什么情况下才要异步,我保留观点,我仅是在调用占用线程时间长的时候才使用异步

  回复  引用  查看    
#18楼2009-03-06 13:53 | Jeffrey Zhao      
@HahahaX
我现在看到“中国人”为主体的命题,一般就直接忽视了,哈哈

  回复  引用  查看    
#19楼[楼主]2009-03-06 15:18 | 重典      
@Jeffrey Zhao
其实任何以一群人为主体的也可以忽略了
比如8090千禧后的问题

  回复  引用  查看    
#20楼2009-03-06 18:00 | Q.Lee.lulu      
@重典
原来00后叫千禧后....

  回复  引用  查看    
#21楼2009-03-07 10:23 | 郁闷的翩翩      
@Q.Lee.lulu
你是说老f啊?

  回复  引用  查看    
#22楼2009-03-07 12:38 | 李春雷      
Mark
  回复  引用  查看    
#23楼2009-03-08 14:18 | 一箭      
悄悄的问题一下,WebService有没有类似的处理.
  回复  引用  查看    
#24楼[楼主]2009-03-08 19:12 | 重典      
@一箭
WebServices本身在调用的时候可以使用Begin-End方式进行调用

  回复  引用  查看    
#25楼2009-03-10 12:15 | 没剑      
楼主有没demo提供啊?谢谢
  回复  引用  查看    
#26楼[楼主]2009-03-10 18:40 | 重典      
@没剑
文章中就是Demo中与一般程序不太一样的地方

  回复  引用  查看    
#27楼[楼主]2009-03-11 09:18 | 重典      
快枪赵今天没发文
  回复  引用    
#28楼2009-04-03 08:59 | EntLib
  回复  引用    
#29楼2009-04-03 09:24 | 重典
@EntLib
你的AEF深入那些篇写的不错,早想认识你了,^^

  回复  引用  查看    
#30楼2009-04-20 17:44 | EntLib      
@重典

谢谢 ~~ ^_^

  回复  引用  查看    
#31楼2009-06-09 16:55 | AGPSky      
Microsoft.Web.Mvc 这个去哪里下载得到啊。谢谢了
  回复  引用  查看    
#32楼[楼主]2009-06-10 00:12 | 重典      
@AGPSky
aspnet.codeplex.com

  回复  引用  查看    
#33楼2010-02-03 15:51 | TOYOE      
頂一下 ^^