WebClient - 等待文件下载完毕 [英] WebClient - wait until file has downloaded

查看:13
本文介绍了WebClient - 等待文件下载完毕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个函数来返回从 xml 文件生成的集合.

I'm developing a function to return a collection, generated from an xml file.

最初,我使用本地 xml 文件进行测试,但现在我已准备好让应用程序从服务器下载真正的 xml 文件.由于需要为 WebClient 对象提供一个 OpenReadCompleted 事件处理程序,我正在努力了解如何做到这一点 - 我无法从中返回收集数据,并且在此处理程序执行时,原始函数已结束.

Initially, I was using a local xml file for testing, but now I'm ready to have the app download the real xml file from a server. I'm struggling to see how I could do this due to the fact a WebClient object needs to be given an OpenReadCompleted event handler - I cannot return the collection data from this, and also by the time this handler executes, the original function has ended.

我的原代码如下:

public static ObservableCollection<OutletViewModel> GetNear(GeoCoordinate location)
{
    ObservableCollection<OutletViewModel> Items = new ObservableCollection<OutletViewModel>();

    // Load a local XML doc to simulate server response for location
    XDocument xDoc = XDocument.Load("SampleRemoteServer/outlet_list.xml");

    foreach (XElement outlet in xDoc.Descendants("outlet"))
    {
        Items.Add(new OutletViewModel()
        {
            Name = outlet.Attribute("name").Value,
            Cuisine = outlet.Attribute("cuisine").Value
        });
    }

    return Items;
}

如何在此函数中加载文件,运行事件处理程序,然后继续执行该函数?

How can I load the file in this function, have the event handler run, and then continue the function?

我唯一能想到的是添加一个循环来继续检查一个变量,该变量由事件处理程序代码更新......这听起来不是一个好的解决方案.

The only was I can think of is to add a loop to keep checking a variable, which is updated by the event handler code... and that doesn't sound like a good solution.

谢谢,乔希

推荐答案

您应该开始了解异步编程.一种(老派)方法是实现一个公共事件并在调用类中订阅该事件.

You should start to take a look at async programming. One (old school) way would be to implement a public event and subscribe to that event in the calling class.

然而,使用回调更优雅.我创建了一个简单(无用,但在概念上仍然有效)的示例,您可以在此基础上进行构建:

However, using callbacks is more elegant. I whipped up a simple (useless, but still conceptually valid) example that you can build upon:

public static void Main(string[] args)
{
  List<string> list = new List<string>();

  GetData(data =>
  {
    foreach (var item in data)
    {
      list.Add(item);
      Console.WriteLine(item);
    }
    Console.WriteLine("Done");
  });
  Console.ReadLine();
}

public static void GetData(Action<IEnumerable<string>> callback)
{
  WebClient webClient = new WebClient();
  webClient.DownloadStringCompleted += (s, e) =>
    {
      List<string> data = new List<string>();
      for (int i = 0; i < 5; i++)
      {
        data.Add(e.Result);
      }
      callback(e.Error == null ? data : Enumerable.Empty<string>());
    };

  webClient.DownloadStringAsync(new Uri("http://www.google.com"));
}

如果您想加入 C# async 潮流 (WP7 实现的链接),您可以使用新的 asyncawait 关键字实现它:

If you want to jump onto the C# async bandwagon (link for WP7 implementation), you can implement it using the new async and await keywords:

public static async void DoSomeThing()
{
  List<string> list = new List<string>();
  list = await GetDataAsync();

  foreach (var item in list)
  {
    Console.WriteLine(item);
  }
}

public static async Task<List<string>> GetDataAsync()
{
  WebClient webClient = new WebClient();
  string result = await webClient.DownloadStringTaskAsync(new Uri("http://www.google.com"));

  List<string> data = new List<string>();
  for (int i = 0; i < 5; i++)
  {
    data.Add(result);
  }
  return data;
}

这篇关于WebClient - 等待文件下载完毕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆