从ASP.NET MVC 2到4看异步控制器

开发 后端
要看异步控制器, 我们首先看看同样功能的同步实现, 大家应该都很熟悉了。这篇文章主要针对即将到来的ASP.NET MVC4中的异步控制器做一个回顾和展望, 并未涉及到讨论异步控制器的使用场合。

  这篇文章主要针对即将到来的ASP.NET MVC4中的异步控制器做一个回顾和展望, 并未涉及到讨论异步控制器的使用场合, 如果对异步控制器何时使用仍然纠结的同学, 这次可能会让你们失望了, 不过关于这方面的讨论和分析其实蛮多的, 大家也可以自行搜索.好了,废话少说,上正文.

  异步控制器

  在MS越来越提倡异步操作的时代, ASP.NET MVC中的异步操作却一直显得比较落伍, 对于开发人员来说, 实现一个异步控制器往往要比普通的控制器花费更多的代码. 这个特性是在ASP.NET MVC 2中被引入的, 之后就没怎么改过,直到现在, 随着C# 5和 async/await的即将到来, 异步控制器现在已经跟普通的控制器操作代码一样的简练啦. 现在(当然得等ASP.NET MVC4,.NET 4.5和C# 5正式的发布之后), 你可以写出下面这样简洁的代码啦:

  1.   publicasync Task<ViewResult> FooBar() {  
  2. returnView(await DoSomething("Some Action"));} 

  怎样? 真的是很简单的吧~~

  展望固然重要, 不过在这之前, 也请大家随着我来回顾下一步控制器在ASP.NET MVC 2到4中的实现, 对比往往更能让人印象深刻.

  注意:下面关于ASP.NET MVC 4的例子都是基于ASP.NET MVC Developer Preview. 在正式版中, 这种实现可能会有所变化.

  在ASP.NET MVC 2/3中的异步控制器

  在ASP.NET MVC 2/3 中, 要实现一个一步控制器,你将不得不实现两个方法, 一个叫XXXAsync, 另外一个叫XXXCompleted, 同时你的控制器还要改成继承自AsyncController, 关于这个的实现和讲解已经有很多现成的例子, 这里我就直接从MSDN上搬过来一个例子吧.

  要看异步控制器, 我们首先看看同样功能的同步实现, 大家应该都很熟悉了:

  1. publicclassPortalController: Controller{publicActionResult News(stringcity){  
  2. NewsService newsService = newNewsService();  
  3. ViewStringModel headlines = newsService.GetHeadlines(city);  
  4. returnView(headlines);}  

  我们再来看其异步实现方式:

  1. publicclassPortalController : AsyncController{  
  2. publicvoidNewsAsync(stringcity){  
  3. AsyncManager.OutstandingOperations.Increment();  
  4. var newsService = newNewsService();  
  5. newsService.GetHeadlinesCompleted += (sender, e) =>{AsyncManager.Parameters["headlines"] = e.Value;AsyncManager.OutstandingOperations.Decrement();};  
  6. newsService.GetHeadlinesAsync(city);  
  7. }  
  8. publicActionResult NewsCompleted(string[] headlines){  
  9. returnView("News", newViewStringModel{NewsHeadlines = headlines});}  
  10. }  

  看看上面的实现, 不得不承认, 相对同步控制器, 异步Action开发人员要做的工作还是要多一些的. 但在.NET4.0的大环境中, 我们也只能用这种方式来实现了.

  当然, MSDN的例子是标准的分层的实现例子, 在这个例子中,你将不得不实现自己的Service层, 如果你只是想简单的调用异步Action, 有没有方便的办法呢? 答案是有的, 在.NET 4.0中,微软带来了Task类, 感兴趣的同学可以猛击这里. 有了Task,如果你只是想简单的一个函数里面做异步操作也是可以滴:

 

  1.   publicclassPortalController : AsyncController {publicvoidNewsAsync(stringcity)
  2. {AsyncManager.OutstandingOperations.Increment();  
  3. var task = Task.Factory.StartNew(() => RunThread(city));  
  4. task.ContinueWith(t =>{AsyncManager.Parameters["headlines"] = t.Result;  
  5. AsyncManager.OutstandingOperations.Decrement();})  
  6. ;}  
  7.   publicActionResult NewsCompleted(string[] headlines){  
  8. returnView("News", newViewStringModel{NewsHeadlines = headlines});}  
  9.   privatestringRunThread(stringinput){  
  10. Thread.Sleep(5000);returninput;}} 

 

  当然, 代码并没有减少太多, 不过也算是一种不太复杂的实现, 虽然没那么好看, 但也不至于太难看.

  下面我们再来看看ASP.NET MVC 4中的异步控制器吧.

  ASP.NET 4 Developer preview中的异步控制器

  在抛弃了对.NET 3的支持之后, ASP.NET MVC 4 彻底拥抱了Task类库, 你不需要再蛋疼的给每个Action写两个方法, 也无需傻傻的手动对异步Action计数器增减了(AsyncManager.OutstandingOperations.Increment()), 现在的你只需拿起手指, 轻轻敲几下, 其他的事情都由系统帮你完成.

 

  1. publicclassPortalController : AsyncController {  
  2. publicTask<ViewResult> News( stringcity) {  
  3. returnTask.Factory.StartNew(() => RunThread(city)).ContinueWith(t => {  
  4. returnView(newViewStringModel(){Text = t.Result});  
  5. });}  
  6. privatestringRunThread(stringinput){  
  7. Thread.Sleep(5000);  
  8. returninput;}  

  是不是好多了?Lamda可以让一切更爽:

  1. publicTask<ViewResult> News(stringcity) {  
  2. returnTask.Factory.StartNew(() => RunThread(city)).ContinueWith(t => View(newViewStringModel{   
  3. Text = t.Result }));  

  那么, 是不是到这里就要说再见了呢? 不是的, 请继续往下看.

  伟大的async/await

  虽然还未到正式发布的时候, 不过如果我们跟着微软的目光往前更进一步, 在ASP.NET和C# 5中, 或者我们从这里可以给.NET 4增加Async 的功能, 在有了async和await这两个关键词之后, 异步编码就更简单啦, 这其中也包括异步控制器的相关操作:

  1. publicclassPortalController : AsyncController {  
  2. publicasyncTask<ViewResult> News(string city)  
  3. {returnView(newViewStringModel(){   
  4. Text = awaitNewThread(city)});}   
  5. privateasync Task<string>NewThread(stringinput)   
  6. { Thread.Sleep(5000);   
  7. returninput; }} 

  总结

  由于有了async和await关键字以及Task类库的帮助, 在可预见的未来里, 我们操作异步控制器就可以像操作普通的控制器一样了, 但就像其他的众多新增的.NET特性一样, 能力越大, 责任也就越大, 方便也往往意味着滥用. 异步控制器固然好, 但也并非每种场合都适合用它, 不恰当的使用它往往会导致服务器需要在不同的线程之间切换, 而这也带来了更多额外的开销. 在开发领域, 我们尤其要注意性能往往比其他任何东西都重要, 因此, 请在确实能提高性能和用户相应的情况下使用异步控制器.

原文链接:http://www.cnblogs.com/jujusharp/archive/2012/02/02/async-controller-from-net-mvc-2-to-4.html

【编辑推荐】

  1. ASP.NET MVC会成为ASP.NET未来主流的UI平台?
  2. ASP.NET性能优化之构建自定义文件缓存
  3. 想爱容易相处难:当ASP.NET MVC爱上IoC
  4. 导致ASP.NET站点重启的十大原因
  5. 浅谈ASP.NET核心对象
责任编辑:彭凡 来源: 博客园
相关推荐

2009-01-12 11:16:58

控制器控制器行为行为结果

2011-08-08 10:46:15

ASP.NET MVC

2009-07-22 10:13:31

异步ActionASP.NET MVC

2012-07-04 14:49:34

ASP.NET

2009-07-22 16:34:36

使用T4ASP.NET MVC

2021-10-19 10:42:00

MVCAPI.NET

2009-03-06 10:28:30

MVCASP.NET异步Action

2009-02-16 10:05:11

ActionMVCASP.NET

2009-02-17 09:22:14

ActionMVCASP.NET

2009-07-24 13:20:44

MVC框架ASP.NET

2009-07-31 12:43:59

ASP.NET MVC

2009-12-18 09:13:31

ASP.NET MVC

2010-02-05 08:32:32

ASP.NET MVC

2011-09-28 13:48:06

Visual Stud

2010-11-15 08:44:38

ASP.NET MVC

2009-07-23 14:31:20

ASP.NET MVC

2009-07-20 10:53:59

ASP.NET MVC

2009-07-23 15:44:39

ASP.NET MVC

2009-07-22 10:09:59

ASP.NET MVC

2009-07-22 13:24:24

ASP.NET MVC
点赞
收藏

51CTO技术栈公众号