본문 바로가기
Programming

RSS Feed를 가져오는 C# 예제를 통한 Async 효율성 테스트

RSS Feed를 가져오는 C# 예제를 통한 Async 효율성 테스트

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace FeedReader
{
    class Program
    {
        static void Main(string[] args)
        {
            var feedUrls = new List<string>()
            {
                "http://www.engadget.com/rss.xml",
                //"http://www.wired.com/feed/",
                "http://apod.nasa.gov/apod.rss",
                "http://arstechnica.com/feed/",
            };
            var stopwatch = Stopwatch.StartNew();
            var feeds = (from url in feedUrls select ReadFeed(url)).ToArray();
            var items = from feed in feeds
                        from channel in XElement.Parse(feed).Elements("channel")
                        from item in channel.Elements("item").Take(2)
                        let date = PublishedData(item)
                        orderby date descending
                        select new
                        {
                            Title = (string)channel.Element("title"),
                            Link = (string)channel.Element("link"),
                            PostTitle = (string)item.Element("title"),
                            PostLink = (string)item.Element("link"),
                            Date = date
                        };
            foreach (var item in items)
            {
                Console.WriteLine("Title : {0} [{1}]", item.Title, item.Link);
                Console.WriteLine("    Post : {0} [{1}]", item.PostTitle, item.PostLink);
                Console.WriteLine("    Date : {0}", item.Date);
                Console.WriteLine("----------------------");
            }
            Console.WriteLine("Total Time: {0}",stopwatch.Elapsed);
            Console.ReadKey();
        }
      
        static string ReadFeed(string url)
        {
            var client = new WebClient()
            {
                CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore)
            };
            var contents = client.DownloadString(url);
            return contents;
        }
        static DateTime PublishedData(XElement item)
        {
            var s = (string)item.Element("pubDate");
            if (s != null)
            {
                s = s.Replace("EST", "-0500");
                s = s.Replace("EDT", "-0400");
                s = s.Replace("CST", "-0600");
                s = s.Replace("CDT", "-0500");
                s = s.Replace("MST", "-0700");
                s = s.Replace("MDT", "-0600");
                s = s.Replace("PST", "-0800");
                s = s.Replace("PDT", "-0700");
            }
            DateTime d;
            if (DateTime.TryParse(s, out d))
            {
                return d;
            }
            return DateTime.MinValue;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace FeedReader
{
    class Program
    {
        static void Main(string[] args)
        {
            ProcessFeedsAsync(args).Wait();
            Console.ReadKey();
        }
        static async Task ProcessFeedsAsync(string[] args)
        {
            var feedUrls = new List<string>()
            {
                "http://www.engadget.com/rss.xml",
                //"http://www.wired.com/feed/",
                "http://apod.nasa.gov/apod.rss",
                "http://arstechnica.com/feed/",
            };
            var stopwatch = Stopwatch.StartNew();
            var feeds = await Task.WhenAll(from url in feedUrls select ReadFeed(url));
            var items = from feed in feeds
                        from channel in XElement.Parse(feed).Elements("channel")
                        from item in channel.Elements("item").Take(2)
                        let date = PublishedData(item)
                        orderby date descending
                        select new
                        {
                            Title = (string)channel.Element("title"),
                            Link = (string)channel.Element("link"),
                            PostTitle = (string)item.Element("title"),
                            PostLink = (string)item.Element("link"),
                            Date = date
                        };
            foreach (var item in items)
            {
                Console.WriteLine("Title : {0} [{1}]", item.Title, item.Link);
                Console.WriteLine("    Post : {0} [{1}]", item.PostTitle, item.PostLink);
                Console.WriteLine("    Date : {0}", item.Date);
                Console.WriteLine("----------------------");
            }
            Console.WriteLine("Total Time: {0}",stopwatch.Elapsed);
        }
      
        static Task<string> ReadFeed(string url)
        {
            var client = new WebClient()
            {
                CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore)
            };
            var contents = client.DownloadStringTaskAsync(url);
            return contents;
        }
        static DateTime PublishedData(XElement item)
        {
            var s = (string)item.Element("pubDate");
            if (s != null)
            {
                s = s.Replace("EST", "-0500");
                s = s.Replace("EDT", "-0400");
                s = s.Replace("CST", "-0600");
                s = s.Replace("CDT", "-0500");
                s = s.Replace("MST", "-0700");
                s = s.Replace("MDT", "-0600");
                s = s.Replace("PST", "-0800");
                s = s.Replace("PDT", "-0700");
            }
            DateTime d;
            if (DateTime.TryParse(s, out d))
            {
                return d;
            }
            return DateTime.MinValue;
        }
    }
}


Async 처리로 RSS feed를 가져오는 경우 테스트 PC에서의 경우 약 4배정도 속도 차가 있음

참고