• 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

       自强不息,奋斗不止!

      

      

       

  • 相关阅读:
    java 之 对象与垃圾回收
    Java 之 内部类
    java 接口(interface)
    抽象类
    Java之fianl修饰符
    类的继承
    上传图片
    一般处理程序 给图片添加文字水印
    socket
    初识linq,lambda表达式
  • 原文地址:https://www.cnblogs.com/feichexia/p/ASPDoNET_DarkMagic_AsyncProgramming.html
Copyright © 2020-2023  润新知