2014-10-28 16 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查詢。