• ASP.NET MVC4中的异步控制器


    ET MVC 2/3中的异步控制器

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

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

    publicclass PortalController: Controller
     {
         public ActionResult News(string city)
         {
             NewsService newsService = new NewsService();
             ViewStringModel headlines = newsService.GetHeadlines(city);
             return View(headlines);
         }
     }

     

       

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

    public class PortalController : AsyncController
     {
         public void NewsAsync(string city)
         {
              AsyncManager.OutstandingOperations.Increment();
              var newsService = new NewsService();
              newsService.GetHeadlinesCompleted += (sender, e) =>
              {
                 AsyncManager.Parameters["headlines"] = e.Value;
                 AsyncManager.OutstandingOperations.Decrement();
             };
             newsService.GetHeadlinesAsync(city);
         }
          public ActionResult NewsCompleted(string[] headlines)
          {
             return View("News", new ViewStringModel
             {
                 NewsHeadlines = headlines
             });
         }
     }

     

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

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

    public class PortalController : AsyncController 
    {
         public void NewsAsync(string city)
         {
             AsyncManager.OutstandingOperations.Increment();
             var task = Task.Factory.StartNew(() => RunThread(city));
             task.ContinueWith(t =>
             {
                 AsyncManager.Parameters["headlines"] = t.Result;
                 AsyncManager.OutstandingOperations.Decrement();
             });
         }
         
        public ActionResult NewsCompleted(string[] headlines)
        {
             return View("News", new ViewStringModel
             {
                 NewsHeadlines = headlines
             });
         }
    
    
         private string  RunThread(string input)
         {
             Thread.Sleep(5000);
             return input;
         }
     }

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

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

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

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

    public class PortalController : AsyncController 
    {
    public Task<ViewResult> News( string city)     
         {
             return Task.Factory.StartNew(() =>  RunThread(city))
                 .ContinueWith(t =>
                                   {
                                       return View(new ViewStringModel()
                                                       {
                                                           Text = t.Result
                                                       });
                                   });
         }
          private string  RunThread(string input)
         {
             Thread.Sleep(5000);
             return input;
         }
     }

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

    public Task<ViewResult> News(string city) {
         return Task.Factory.StartNew(() => RunThread(city))
             .ContinueWith(t => View(new  ViewStringModel{ Text = t.Result }));
     }

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

    伟大的async/await

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

    public class PortalController : AsyncController {
         public async Task<ViewResult> News(string city)
         {
             return View(new  ViewStringModel()
                             {                             
                               Text = await NewThread(city)
                             });
         }      
        private async Task<string> NewThread(string input)    
        {         
             Thread.Sleep(5000);         
             return input; 
        }
     }

     

    总结

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

    作者:Sean Zhu
    出处:http://jujusharp.cnblogs.com 
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    α波、β波、θ波和δ波
    出体的真实性
    FreeBSD查看网络情况
    灰色理论预测模型
    主成分分析法
    常用OJ名字+地址(自用)
    2017 年“认证杯”数学中国数学建模网络挑战赛 比赛心得
    Codeforces Round #404 (Div. 2)(A.水,暴力,B,排序,贪心)
    hihoCoder #1053 : 居民迁移(贪心,二分搜索,google在线技术笔试模拟)
    Codeforces Round #408 (Div. 2)(A.水,B,模拟)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2336819.html
Copyright © 2020-2023  润新知