たくさんのRSSアイテムを取得するためにReactiveExtensionsを試しています。私はTimGreenfieldによるブログ投稿に基づいています:MVVM内のSilverlightRxDataClient。
デスクトップアプリケーション内で使用していますが、コードは似ています。
私が抱えている問題は、Retry()
機能を理解することです。それは私が期待していること、そして私が期待していることをしているようには見えません。
var items = new List<RssItem>();
WebHelper.DownloadXmlFileAsync<RssItem>(new Uri(URI), "item")
.Retry(2)
.Finally(PublishResults)
.Subscribe(items.Add, ProcessError, () => ProcessCompleted(items));
有効なURIを渡すと、これは問題なく機能します。URIにタイプミスをすると、ProcessError()
予想どおり、関数を介して404エラーが報告されますが、報告されるのは1回だけです。このエラーが2回表示されると思っていました。
したがって、このRetry()
関数は私のWebリクエストでは機能していないようですが、に渡される関数には実際に適用されているようSubscribe()
です。私はここで間違っている可能性があります。
Retry()
通話がWebリクエストに適用されることを確認するにはどうすればよいですか?
追加コード:
public static class WebHelper
{
public static HttpWebRequest CreateHttp(Uri uri)
{
return CreateHttp(uri, "GET");
}
public static HttpWebRequest CreateHttp(Uri uri, string method)
{
if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)
{
throw new ArgumentException("The specified URI does not use HTTP or HTTPS.", "uri");
}
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = method;
return request;
}
public static IObservable<T> DownloadXmlFileAsync<T>(Uri uri, string elementName) where T : class
{
return (from request in Observable.Return(CreateHttp(uri))
from response in Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)()
let stream = response.GetResponseStream()
where stream != null
from item in XmlReader.Create(stream).GetXmlItem<T>(elementName).ToObservable()
select item);
}
}
public static class XmlExtensions
{
public static IEnumerable<T> GetXmlItem<T>(this XmlReader reader, string elementName) where T : class
{
var serializer = new XmlSerializer(typeof (T));
while (reader.GoToElement(elementName))
{
yield return serializer.Deserialize(reader) as T;
}
}
public static bool GoToElement(this XmlReader reader, string elementName)
{
do
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == elementName)
{
return true;
}
} while (reader.Read());
return false;
}
}
XmlRoot("item")]
public class RssItem
{
[XmlElement("description")]
public string Description { get; set; }
[XmlElement("link")]
public string Link { get; set; }
[XmlElement("pubDate")]
public string PublishDate { get; set; }
[XmlElement("title")]
public string Title { get; set; }
public override string ToString()
{
return string.Format("Title: {0}", Title);
}
}