Использование async и await в WP7 / WP8
Долгое время я отказывался от их использования, т.к. в WP7 без сторонних библиотек это не работает, да и включать их, когда уже всё протестировано и написано по старинке, как-то не хотелось. И вот момент настал.
Зачем это вообще надо? В общем случае, чтобы избавиться от множественных Callback и упростить код, по сути, это так любимый многими в .NET синтаксический сахар.
В WP8 всё это чудо работает из коробки, в WP7 необходимо подключить через NuGet Microsoft.Bcl.Async
Пример запроса списка треков из vk.com:
public static class VKapi { private static string _token; private static string _uid; public static void Init(string token, string userid) { _token = token; _uid = userid; } public async static Task<ObservableCollection<Track>> GetList() { WebClient w = CreateWebClient(); Task<string> task = w.UploadStringTaskAsync(new Uri("https://api.vk.com/method/audio.get"), "POST", "owner_id=" + _uid + "&need_user=0&count=0&v=4.99" + "&access_token=" + _token); string result=await ProcessAsync(task); var corrected = System.Text.RegularExpressions.Regex.Replace(result, @"(?<=response\D*)\d[^{]*", string.Empty); return Deserialise<MusicCollection>(corrected).data; } async static Task<string> ProcessAsync(Task<string> task) { await TaskEx.WhenAny(task); if (task.Exception == null) { if (task.Result.StartsWith("{\"error\"")) // Стоит помнить, что ошибки нужно корректно обрабатывать return null; System.Diagnostics.Debug.WriteLine("{SUCCESS REQUEST}"); return task.Result; } else { System.Diagnostics.Debug.WriteLine("{ERROR REQUEST: } " + task.Exception.Message); return null; } } public static T Deserialise<T>(string json) { T obj = Activator.CreateInstance<T>(); using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(json))) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); obj = (T)serializer.ReadObject(stream); return obj; } } private static WebClient CreateWebClient() { WebClient client = new WebClient(); client.Headers["Accept"] = "*/*"; client.Headers["code"] = "asO1pjUgf4TnLQFn3ylh"; client.Headers["Content-Type"] = "application/x-www-form-urlencoded"; return client; } }
Пример того, как мы этим пользуемся:
[DataContract] public class MusicCollection { [DataMember(Name="response")] public ObservableCollection<Track> data { get; set; } public async Task<bool> GetVKdata() { data = await VKapi.GetList(); if (data == null) return false; return true; } }
Никаких Callback, повышенная гибкость и разделение кода, сплошная радость.
Другие примеры и более подробная информация:
Async CTP – Task based asynchronous programming for Windows Phone
Вот ешё можно почитать:
http://developer.nokia.com/Community/Wiki/Asynchronous_Programming_For_Windows_Phone_8
http://msdn.microsoft.com/ru-ru/library/hh156528.aspx