【问题标题】:Simple way to add foreach loop around WebClient在 WebClient 周围添加 foreach 循环的简单方法
【发布时间】:2014-12-24 02:08:33
【问题描述】:

我尝试围绕WebClient 任务添加foreach 循环,但它似乎不起作用。我做了一些研究,发现有一些干净的方法可以解决这个问题,比如让系统休眠一秒钟,我想要一个更有条理的解决方案。如果没有解决方案,我还能如何使用 W8 手机从互联网上读取 RSS 提要。

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);
}

【问题讨论】:

  • 此代码示例是否完整,您似乎根本没有在循环中使用 rssFeed 变量,那么为什么要循环?
  • 您说它“似乎不起作用”。您是否收到特定的错误消息,或者它是否运行完成但没有给出预期的结果,或者是什么?
  • 您的实际问题可能是在循环中调用 WebClient 的异步方法吗?我不确定 WP8 平台的限制,但通常可以使用 await 解决
  • 看看之前的SO 发帖,不确定它是否适用于您正在尝试做的事情,但看起来可能stackoverflow.com/questions/13505967/…
  • @J.Marciniak 他没有覆盖它,不。该变量正在离开范围并在循环的每次迭代中重新声明。那是不同的东西,也根本不是问题。

标签: c# xml windows-phone-8 foreach webclient


【解决方案1】:

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

例如:

我们可以通过创建ListKeyValuePair 来实现下载管理器。 KeyValuePair 将有一个 Key 基本上是网站的 URL 和网站的 HTML(或下载的内容)的 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);
        }            
    }
}

现在设置一个断点。并观察下载管理器填满数据。这是下载管理器的截图,注意它的组织方式。网站/数据组合应该非常简单易懂。

Click Here For Full Size Image

【讨论】:

    【解决方案2】:

    我会为此使用 Microsoft Reactive Framework (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 基本上是一个使用 Observables 而不是 Enumerables 的异步 LINQ 查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 2013-02-11
      相关资源
      最近更新 更多