2014-10-28 50 views
0

我试图在WebClient任务的周围添加一个foreach循环,但似乎不起作用。我做了一些研究,发现有一些干净的方法可以解决这个问题,比如让系统进入睡眠状态一秒钟,我想要一个更加结构化的解决方案。如果没有解决方案我还可以通过W8手机从互联网上阅读RSS源。在WebClient周围添加foreach循环的简单方法

foreach (string rssFeed in lstRSSFeeds) 
{ 
    // our web downloader 
    WebClient downloader = new WebClient(); 

    // our web address to download, notice the UriKind.Absolute 
    Uri uri = new Uri(rssFeed, UriKind.Absolute); 

    // we need to wait for the file to download completely, so lets hook the DownloadComplete Event 
    downloader.DownloadStringCompleted += new DownloadStringCompletedEventHandler(FileDownloadComplete); 

    // start the download 
    downloader.DownloadStringAsync(uri); 
} 
+0

该代码示例是否完整,它没有出现在循环中使用rssFeed变量,那么为什么循环呢? – 2014-10-28 15:38:33

+3

你说它“似乎没有工作”。您是否收到特定的错误消息,或者正在运行到完成但未提供期望的结果或什么? – 2014-10-28 15:38:35

+0

难道你的实际问题是在循环内调用WebClient的异步方法吗?我不确定WP8平台的限制,但通常可以使用[await](http://msdn.microsoft.com/zh-cn/library/hh156528.aspx) – Filburt 2014-10-28 15:38:36

回答

0

如果你想下载多个文件,最好是实现某种下载管理器。这听起来很难,但我向你保证它不是。

例如:

我们可以通过创建一个KeyValuePair实施List一个下载管理器。 KeyValuePair将有一个Key这基本上是该网站的HTML(或下载的内容)的网站的URL和Value

我们将使用您的foreach方案下载文件。


public partial class MainPage : PhoneApplicationPage 
{ 

    // our simple download manager 
    List<KeyValuePair<string, string>> DownloadManager = new List<KeyValuePair<string, string>>(); 

    // Constructor 
    public MainPage() 
    { 
     InitializeComponent(); 

     // create our list of websites to download 
     List<string> lstRSSFeeds = new List<string>(); 

     // lets add 3 web sites 
     lstRSSFeeds.Add("http://www.google.com"); 
     lstRSSFeeds.Add("http://www.msn.com"); 
     lstRSSFeeds.Add("http://www.chubosaurus.com"); 

     // for each website in the list, download its data 
     foreach (string rssFeed in lstRSSFeeds) 
     { 
      // our web downloader 
      WebClient downloader = new WebClient(); 

      // our web address to download, notice the UriKind.Absolute 
      Uri uri = new Uri(rssFeed, UriKind.Absolute); 
      downloader.BaseAddress = uri.ToString(); 

      // we need to wait for the file to download completely, so lets hook the DownloadComplete Event 
      downloader.DownloadStringCompleted += new DownloadStringCompletedEventHandler(FileDownloadComplete); 

      // start the download 
      downloader.DownloadStringAsync(uri); 
     } 
    } 

    // this event will fire if the download was successful 
    // we will save all the data to the DownloadManager 
    void FileDownloadComplete(object sender, DownloadStringCompletedEventArgs e) 
    { 
     // error check 
     if (!e.Cancelled && e.Error == null) 
     { 
      string uri = ((WebClient)sender).BaseAddress; // set the key to the base address (url) 
      string html = e.Result;       // save the html 

      // create the KeyValuePair (this will save all the html and be indexed by the url) 
      KeyValuePair<string, string> site_data = new KeyValuePair<string, string>(uri, html); 

      // add the KeyValuePair to our download manager 
      DownloadManager.Add(site_data); 
     }    
    } 
} 

现在设置一个断点。并观看DownloadManager,因为它填满了数据。下面是DownloadManager的截图,注意它是如何组织的。网站/数据组合应该非常简单,以便您理解。

Click Here For Full Size Image enter image description here

0

我会使用Microsoft无框架(Rx)的这一点。它处理所有异步调用,并可用于清除WebClient(这是一个IDisposable)。

方法如下:

var query = 
    from rssFeed in lstRSSFeeds.ToObservable(Scheduler.Default) 
    from content in Observable.Using(
     () => new WebClient(), 
     wc => Observable.FromAsync(
      () => wc.DownloadStringTaskAsync(new Uri(rssFeed, UriKind.Absolute)))) 
    select new { rssFeed, content }; 

query.Subscribe(result => 
{ 
    // do something with each 
    // `result.rssFee` & `result.content` 
}); 

的Rx基本上是采用观测量,而不是可枚举异步LINQ查询。