The other day I had a snazzy post on fetching all the video (WMV) files from Mix ‘10. A simple, console application that grabbed the urls from the OData feed and downloaded the videos. I wanted to change that app to fire the OData query asynchronously so here’s what resulted: 1: static void Main(string[] args)
2: {
3: var mix = new Mix.EventEntities(new Uri("http://api.visitmix.com/OData.svc"));
4:
5: var temp = mix.Files.Where(f => f.TypeName == "WMV");
6: var query = temp as DataServiceQuery<Mix.File>;
7:
8: query.BeginExecute(OnFileQueryComplete, query);
9:
10: // waiting...
11: Console.ReadLine();
12: }
13:
14: static void OnFileQueryComplete(IAsyncResult result)
15: {
16: var query = result.AsyncState as DataServiceQuery<Mix.File>;
17: var response = query.EndExecute(result);
18:
19: var web = new WebClient();
20:
21: var myVideos = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyVideos), "Mix10");
22:
23: Directory.CreateDirectory(myVideos);
24:
25: foreach (Mix.File f in response)
26: {
27: var fileName = new Uri(f.Url).Segments.Last();
28: Console.WriteLine(f.Url);
29: web.DownloadFile(f.Url, Path.Combine(myVideos, fileName));
30: }
31: }
There are two important things here that are not explained well in the MSDN docs:
See lines 5 and 6? That’s where I query for the WMV files and it returns an IQueryable<T>. You *have* to cast that to a DataServiceQuery<T> and then call BeginExecute. The documented example does not filter so it didn’t show that step.
Line 16 shows the correct way to get the previously executed DataServiceQuery<T> from the async result. If you looked at the MSDN example docs it shows (incorrectly) just casting the result, like this:
// wrong
var query = result as DataServiceQuery<Mix.File>;
Other than those items it is relatively straight forward and we’re all async-ified. Enjoy!