• ASP.NET MVC中的Dark Magic之异步编程


    参考自:http://www.codeguru.com/csharp/.net/net_asp/mvc/working-with-asynchronous-operations-in-asp.net-mvc.htm

       ASP.NET MVC 4加入了async关键词,使得异步编程变得很容易,但本文不是关于这个的,而是关于另外一个我没见过的实现ASP.NET MVC异步编程的方法,我估计很多人也没见过,所以我称之为Dark Magic(不常见但可能比较强大的东东)。

       先看一段代码:

    public void Foo() {
       A();
       B();
       C();
    }

       A()、B()、C()如果是远程方法调用,且三个方法互不影响,那么Foo()方法执行完成的时间就等于三个方法执行的时间之和,因为三个方法串行执行。

       这时就是异步编程大放光彩的时候了,如果采用异步编程,那么Foo()方法执行完成的时间等于A、B、C三个方法的执行时间的最大值。

       直入主题,ASP.NET MVC中如何异步编程实现呢(不考虑ASP.NET MVC 4的async)?

       上代码:

    public class HomeController: AsyncController
    {
       public void IndexAsync()
       {
    
       }
    
       public ActionResult IndexCompleted(...)
       {
    
       }
    }

       

       观察下,控制器HomeController继承自AsyncController,并且多了两个Action。第一个Action名称后缀必需为Async,在这个Action方法里执行异步操作。第二个Action以Completed结尾,表示异步操作执行完成后做的事情。

       假设我们现在要实现一个获取Google RSS News和MSN RSS News的应用,代码大概如下:

    public class HomeController : AsyncController
    {
        private void GetGoogleNews()
        {
        }
     
        private void GetMSNNews()
        {
        }
     
        public void IndexAsync()
        {
        }
     
        public ActionResult IndexCompleted()
        {
        }
    }

       很明显,获取Google News和MSN News这两个任务可以异步执行。

       IndexAsync的实现如下:

    public void IndexAsync()
    {
        AsyncManager.OutstandingOperations.Increment(2);
        Task.Factory.StartNew(() => GetGoogleNews()); 
        Task.Factory.StartNew(() => GetMSNNews()); 
    }

       有点奇特,只说下第一行代码,Increment(2)表明还有2个异步任务待执行。

       GetGoogleNews和GetMSNNews的实现如下:

    private void GetGoogleNews()
    {
        XmlReader reader = XmlReader.Create("http://news.google.co.in/news?pz=1&cf=all&ned=in&hl=en&output=rss");
        Rss20FeedFormatter formatter = new Rss20FeedFormatter();
        formatter.ReadFrom(reader);
        reader.Close();
        AsyncManager.Parameters.Add("GoogleNews", formatter.Feed.Items);
        AsyncManager.OutstandingOperations.Decrement();
    }
     
    private void GetMSNNews()
    {
        XmlReader reader = XmlReader.Create("http://msn.com/rss/news.aspx");
        Rss20FeedFormatter formatter = new Rss20FeedFormatter();
        formatter.ReadFrom(reader);
        reader.Close();
        AsyncManager.Parameters.Add("MSNNews", formatter.Feed.Items);
        AsyncManager.OutstandingOperations.Decrement();
    }

       关注AsyncManager.Parameters.Add(...),它使用了AsyncManager对象的参数集合来保存异步任务执行完成后的结果数据。

       然后AsyncManager.OutstandingOperations.Decrement()方法用来表示待执行的异步任务又完成了一个。

       之后是IndexCompleted的实现:

    public ActionResult IndexCompleted(IEnumerable<SyndicationItem> GoogleNews, IEnumerable<SyndicationItem> MSNNews)
    {
        List<SyndicationItem> allItems = new List<SyndicationItem>();
        allItems.AddRange(GoogleNews);
        allItems.AddRange(MSNNews);
        allItems.Sort(CompareDates);
        ViewBag.FeedItems = allItems;
        return View();
    }

       注意这里的参数IEnumerable<SyndicationItem> GoogleNews和IEnumerable<SyndicationItem> MSNNews,它们分别对应上面AsyncManager对象的参数结合中保存的两个结果数据。

       最后是前台代码实现了:

    <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
    <%@ Import Namespace="System.ServiceModel.Syndication" %>
     
    <!DOCTYPE html>
     
    <html>
    <head runat="server">
        <title>Index</title>
    </head>
    <body>
        <div>
        <table border="1" cellpadding="6" cellspacing="0">
        <tr><th>Latest News from Google and MSN</th></tr>
        <%foreach (SyndicationItem item in ViewBag.FeedItems)
          {%>
          <tr><td><a href="<%= item.Links[0].Uri %>"><%= item.Title.Text %></a></td></tr>
        <%}%>
        </table>
        </div>
    </body>
    </html>

       访问时输入类似下面的URL即可:

    http://localhost:4078/home/index

       自强不息,奋斗不止!

      

      

       

  • 相关阅读:
    wampserver2.2e-php5.3.13 版本 增加 php7 支持
    23种设计模式[3]:抽象工厂模式
    23种设计模式[2]:工厂方法模式
    23种设计模式[1]:单例模式
    [转]设计模式六大原则[6]:开闭原则
    [转]设计模式六大原则[5]:迪米特法则
    [转]设计模式六大原则[4]:接口隔离原则
    [转]设计模式六大原则[3]:依赖倒置原则
    [转]设计模式六大原则[2]:里氏替换原则
    [转]设计模式六大原则[1]:单一职责原则
  • 原文地址:https://www.cnblogs.com/feichexia/p/ASPDoNET_DarkMagic_AsyncProgramming.html
Copyright © 2020-2023  润新知