1- using System . ServiceModel . Syndication ;
1+ using System . Net . Http ;
2+ using System . ServiceModel . Syndication ;
23using System . Xml ;
34
45namespace SimpleFeedReader ;
@@ -18,6 +19,8 @@ namespace SimpleFeedReader;
1819/// </param>
1920public class FeedReader ( IFeedItemNormalizer defaultFeedItemNormalizer , bool throwOnError )
2021{
22+ private static readonly HttpClient _httpclient = new ( ) ;
23+
2124 /// <summary>
2225 /// Gets the default FeedItemNormalizer the <see cref="FeedReader"/> will use when normalizing
2326 /// <see cref="SyndicationItem"/>s.
@@ -60,10 +63,11 @@ public FeedReader(IFeedItemNormalizer defaultFeedItemNormalizer)
6063 /// </summary>
6164 /// <param name="uris">The uri's of the feeds to retrieve.</param>
6265 /// <returns>
63- /// Returns an <see cref="IEnumerable< FeedItem> "/> of retrieved <see cref="FeedItem"/>s.
66+ /// Returns a task that resolves to an <see cref="IEnumerable{ FeedItem} "/> of retrieved <see cref="FeedItem"/>s.
6467 /// </returns>
6568 /// <remarks>This is a convenience method.</remarks>
66- public IEnumerable < FeedItem > RetrieveFeeds ( IEnumerable < string > uris ) => RetrieveFeeds ( uris , DefaultNormalizer ) ;
69+ public Task < IEnumerable < FeedItem > > RetrieveFeedsAsync ( IEnumerable < string > uris )
70+ => RetrieveFeedsAsync ( uris , DefaultNormalizer ) ;
6771
6872 /// <summary>
6973 /// Retrieves the specified feeds.
@@ -73,29 +77,26 @@ public FeedReader(IFeedItemNormalizer defaultFeedItemNormalizer)
7377 /// The <see cref="IFeedItemNormalizer"/> to use when normalizing <see cref="FeedItem"/>s.
7478 /// </param>
7579 /// <returns>
76- /// Returns an <see cref="IEnumerable< FeedItem> "/> of retrieved <see cref="FeedItem"/>s.
80+ /// Returns a task that resolves to an <see cref="IEnumerable{ FeedItem} "/> of retrieved <see cref="FeedItem"/>s.
7781 /// </returns>
7882 /// <remarks>This is a convenience method.</remarks>
79- public IEnumerable < FeedItem > RetrieveFeeds ( IEnumerable < string > uris , IFeedItemNormalizer normalizer )
83+ public async Task < IEnumerable < FeedItem > > RetrieveFeedsAsync ( IEnumerable < string > uris , IFeedItemNormalizer normalizer )
8084 {
81- var items = new List < FeedItem > ( ) ;
82- foreach ( var u in uris )
83- {
84- items . AddRange ( RetrieveFeed ( u , normalizer ) ) ;
85- }
85+ var tasks = uris . Select ( uri => RetrieveFeedAsync ( uri , normalizer ) ) ;
86+ await Task . WhenAll ( tasks ) ;
8687
87- return items ;
88+ return tasks . SelectMany ( tasks => tasks . Result ) ;
8889 }
8990
9091 /// <summary>
9192 /// Retrieves the specified feed.
9293 /// </summary>
9394 /// <param name="uri">The uri of the feed to retrieve.</param>
9495 /// <returns>
95- /// Returns an <see cref="IEnumerable< FeedItem> "/> of retrieved <see cref="FeedItem"/>s.
96+ /// Returns a task that resolves to an <see cref="IEnumerable{ FeedItem} "/> of retrieved <see cref="FeedItem"/>s.
9697 /// </returns>
97- public IEnumerable < FeedItem > RetrieveFeed ( string uri )
98- => RetrieveFeed ( uri , DefaultNormalizer ) ;
98+ public Task < IEnumerable < FeedItem > > RetrieveFeedAsync ( string uri )
99+ => RetrieveFeedAsync ( uri , DefaultNormalizer ) ;
99100
100101 /// <summary>
101102 /// Retrieves the specified feed.
@@ -105,13 +106,14 @@ public IEnumerable<FeedItem> RetrieveFeed(string uri)
105106 /// The <see cref="IFeedItemNormalizer"/> to use when normalizing <see cref="FeedItem"/>s.
106107 /// </param>
107108 /// <returns>
108- /// Returns an <see cref="IEnumerable< FeedItem> "/> of retrieved <see cref="FeedItem"/>s.
109+ /// Returns a task that resolves to an <see cref="IEnumerable{ FeedItem} "/> of retrieved <see cref="FeedItem"/>s.
109110 /// </returns>
110- public IEnumerable < FeedItem > RetrieveFeed ( string uri , IFeedItemNormalizer normalizer )
111+ public async Task < IEnumerable < FeedItem > > RetrieveFeedAsync ( string uri , IFeedItemNormalizer normalizer )
111112 {
112113 try
113114 {
114- return RetrieveFeed ( XmlReader . Create ( uri ) , normalizer ) ;
115+ using var reader = await GetXmlReaderAsync ( uri ) ;
116+ return await RetrieveFeedAsync ( reader , normalizer ) ;
115117 }
116118 catch
117119 {
@@ -128,9 +130,10 @@ public IEnumerable<FeedItem> RetrieveFeed(string uri, IFeedItemNormalizer normal
128130 /// </summary>
129131 /// <param name="xmlReader">The <see cref="XmlReader"/> to use to read the items from.</param>
130132 /// <returns>
131- /// Returns an <see cref="IEnumerable< FeedItem> "/> of retrieved <see cref="FeedItem"/>s.
133+ /// Returns a task that resolves to an <see cref="IEnumerable{ FeedItem} "/> of retrieved <see cref="FeedItem"/>s.
132134 /// </returns>
133- public IEnumerable < FeedItem > RetrieveFeed ( XmlReader xmlReader ) => RetrieveFeed ( xmlReader , DefaultNormalizer ) ;
135+ public Task < IEnumerable < FeedItem > > RetrieveFeedAsync ( XmlReader xmlReader ) =>
136+ RetrieveFeedAsync ( xmlReader , DefaultNormalizer ) ;
134137
135138 /// <summary>
136139 /// Retrieves the specified feed.
@@ -140,9 +143,9 @@ public IEnumerable<FeedItem> RetrieveFeed(string uri, IFeedItemNormalizer normal
140143 /// The <see cref="IFeedItemNormalizer"/> to use when normalizing <see cref="FeedItem"/>s.
141144 /// </param>
142145 /// <returns>
143- /// Returns an <see cref="IEnumerable< FeedItem> "/> of retrieved <see cref="FeedItem"/>s.
146+ /// Returns a task that resolves to an <see cref="IEnumerable{ FeedItem} "/> of retrieved <see cref="FeedItem"/>s.
144147 /// </returns>
145- public IEnumerable < FeedItem > RetrieveFeed ( XmlReader xmlReader , IFeedItemNormalizer normalizer )
148+ public Task < IEnumerable < FeedItem > > RetrieveFeedAsync ( XmlReader xmlReader , IFeedItemNormalizer normalizer )
146149 {
147150 if ( xmlReader == null )
148151 {
@@ -154,14 +157,10 @@ public IEnumerable<FeedItem> RetrieveFeed(XmlReader xmlReader, IFeedItemNormaliz
154157 throw new ArgumentNullException ( nameof ( normalizer ) ) ;
155158 }
156159
157- var items = new List < FeedItem > ( ) ;
158160 try
159161 {
160162 var feed = SyndicationFeed . Load ( xmlReader ) ;
161- foreach ( var item in feed . Items )
162- {
163- items . Add ( normalizer . Normalize ( feed , item ) ) ;
164- }
163+ return Task . FromResult ( feed . Items . Select ( item => normalizer . Normalize ( feed , item ) ) ) ;
165164 }
166165 catch
167166 {
@@ -170,6 +169,23 @@ public IEnumerable<FeedItem> RetrieveFeed(XmlReader xmlReader, IFeedItemNormaliz
170169 throw ;
171170 }
172171 }
173- return items ;
172+ return Task . FromResult ( Enumerable . Empty < FeedItem > ( ) ) ;
173+ }
174+
175+ private static async Task < XmlReader > GetXmlReaderAsync ( string uri )
176+ {
177+ if ( Uri . IsWellFormedUriString ( uri , UriKind . Absolute ) )
178+ {
179+ var response = await _httpclient . GetAsync ( uri ) ;
180+ response . EnsureSuccessStatusCode ( ) ;
181+ var stream = await response . Content . ReadAsStreamAsync ( ) ;
182+ return XmlReader . Create ( stream ) ;
183+ }
184+ else if ( File . Exists ( uri ) )
185+ {
186+ var stream = File . OpenRead ( uri ) ;
187+ return XmlReader . Create ( stream ) ;
188+ }
189+ throw new FileNotFoundException ( $ "The file '{ uri } ' was not found.") ;
174190 }
175191}
0 commit comments