WebClient – 等待文件下载
我正在开发一个函数来返回一个从xml文件生成的集合。
最初,我使用本地xml文件进行测试,但现在我已准备好让应用程序从服务器下载真正的xml文件。 我很难看到如何做到这一点,因为WebClient
对象需要被赋予一个OpenReadCompleted
事件处理程序 – 我无法从此返回集合数据,并且在此处理程序执行时,原始函数已经结束。
我原来的代码如下:
public static ObservableCollection GetNear(GeoCoordinate location) { ObservableCollection Items = new ObservableCollection(); // 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; }
如何在此函数中加载文件,运行事件处理程序,然后继续该函数?
唯一可以想到的是添加一个循环来继续检查一个变量,该变量由事件处理程序代码更新……这听起来不是一个好的解决方案。
谢谢,乔希
你应该开始看一下异步编程。 一种(旧学校)方式是实现公共事件并在调用类中订阅该事件。
但是,使用回调更优雅。 我掀起了一个你可以构建的简单(无用,但仍然是概念上有效)的例子:
public static void Main(string[] args) { List list = new List (); GetData(data => { foreach (var item in data) { list.Add(item); Console.WriteLine(item); } Console.WriteLine("Done"); }); Console.ReadLine(); } public static void GetData(Action> callback) { WebClient webClient = new WebClient(); webClient.DownloadStringCompleted += (s, e) => { List data = new List (); for (int i = 0; i < 5; i++) { data.Add(e.Result); } callback(e.Error == null ? data : Enumerable.Empty ()); }; webClient.DownloadStringAsync(new Uri("http://www.google.com")); }
如果你想跳转到C# async
行列( WP7实现的链接 ),你可以使用新的async
和await
关键字来实现它:
public static async void DoSomeThing() { List list = new List (); list = await GetDataAsync(); foreach (var item in list) { Console.WriteLine(item); } } public static async Task> GetDataAsync() { WebClient webClient = new WebClient(); string result = await webClient.DownloadStringTaskAsync(new Uri("http://www.google.com")); List data = new List (); for (int i = 0; i < 5; i++) { data.Add(result); } return data; }
您将foreach()
循环移动到已完成的事件。
这确实意味着你不能从原始方法返回任何东西。 把它变成一个void
。
这就是异步I / O的工作原理,最好习惯它。 您需要重新考虑您的设计。