WebClient-等待文件下载完毕 [英] WebClient - wait until file has downloaded
问题描述
我正在开发一个函数来返回从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#异步
潮流(WP7实现的链接),则可以使用新的 async
和 await
关键字来实现它:
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屋!