WebClient-等待文件下载
本文关键字:文件下载 等待 WebClient- | 更新日期: 2023-09-27 18:27:52
我正在开发一个函数来返回从xml文件生成的集合。
最初,我使用本地xml文件进行测试,但现在我已经准备好让应用程序从服务器下载真正的xml文件了。由于WebClient
对象需要给定一个OpenReadCompleted
事件处理程序,我很难理解如何做到这一点——我无法从中返回集合数据,而且当这个处理程序执行时,原始函数已经结束。
我的原始代码如下:
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;
}
如何在该函数中加载文件,运行事件处理程序,然后继续该函数?
我唯一能想到的就是添加一个循环来不断检查一个变量,该变量由事件处理程序代码更新。。。这听起来不是一个好的解决方案。
谢谢,Josh
将foreach()
循环移动到已完成的事件。
这确实意味着您不能从原始方法返回任何内容。使其成为void
。
异步I/O就是这样工作的,最好习惯它。你需要重新思考你的设计。
您应该开始了解异步编程。一种(老派)方法是实现一个公共事件,并在调用类中订阅该事件。
然而,使用回调更为优雅。我举了一个简单的(无用的,但在概念上仍然有效的)例子,你可以建立在这个例子的基础上:
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实现的链接),你可以使用新的async
和await
关键字来实现它:
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;
}