在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
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 自强不息,奋斗不止!
|
请发表评论