html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Async/await в Windows Phone 7.x и 8 из песочницы

Здравствуйте, уважаемые хабровчане!

В своей дебютной статье я хотел бы рассказать об использовании механизма async/await в C# 5.0 (и .NET Framework 4.5) при программировании для Windows Phone 7.x и 8.
Я занимаюсь программированием не только на работе, в последнее время я увлёкся разработкой под мобильные операционные системы и нахожу это весьма занимательным. А поскольку я давно погрузился в мир Microsoft, то первой и пока единственной платформой для меня стала Windows Phone.

Суть вопроса


На самом деле, с самого анонса C# 5.0 в далёком 2010 году было ясно, что механизм async/await — это то, что, попробовав однажды, программист захочет использовать везде, где это уместно. Действительно: ведь вместо того, чтобы писать порой достаточно сложный многопоточный код с последующей синхронизацией получившихся потоков, достаточно всего лишь использовать один из доступных async-методов или же обернуть уже существующий код в async.

Вся соль состоит в том, что если писать под Windows Phone, то по возможности (пока ещё) нужно поддерживать не только 8-ую версию, но и 7.5/7.8 — это как минимум правило хорошего тона, а вообще разработчик от этого только выигрывает. Но Windows Phone 7.x «из коробки» не поддерживает async/await, а это значит, что либо у вас получится огромное количество асинхронного кода, написанного «традиционными» средствами, либо выйдет что-то наподобие некоторых имеющихся в Магазине приложений, запускающихся столько времени, сколько уйдёт у смартфона на загрузку контента. И то, и другое — определённо не есть хорошо.

Решение


Решить эту проблему призван NuGet-пакет Microsoft.Bcl.Async, первая версия которого появилась ещё в октябре 2012 г., а финальный релиз состоялся всего около недели назад. Пакет поддерживает не только Windows Phone, но и «взрослый» .NET Framework 4.0 (с обновлением KB2468871, справедливости ради), Silverlight 4 и 5, ну и соответствующие Portable Class Libraries. Использовать его можно только в Visual Studio 2012 — видимо, реализация поддержки ключевых слов async/await в 2010-й «студии» себя не оправдала, по крайней мере в глазах Microsoft.
Кстати, что странно: на Хабре про этот пакет я нашёл совсем немного упоминаний.

Дальше идёт несколько выжимок из официального анонса релиза Microsoft.Bcl.Async в блоге BCL.

Во-первых, Microsoft.Bcl.Async полностью заменяет собой выпускавшийся ранее «Async Targeting Pack» (Microsoft.CompilerServices.AsyncTargetingPack). Не в том смысле, что Async Targeting Pack обновится через NuGet до Bcl.Async, а в плане прекращения его разработки и настойчивой рекомендации заменить его на новый пакет. В принципе, такое обновление проходит безболезненно.

Во-вторых, для установки Microsoft.Bcl.Async понадобится версия NuGet 2.1 или выше. Обновляется через менеджер расширений Visual Studio и не вызывает никаких проблем. Просто для информации: если NuGet ругается, проверьте его версию.

В-третьих, из-за использования механизма унификации сборок, все сборки, использующиеся функциональность async/await, должны содержать ссылки на необходимые пакеты (Microsoft.Bcl.Async, Microsoft.Bcl и Microsoft.Bcl.Build). В финальной версии пакета разработчики добавили соответствующее предупреждение, возникающее в процессе компиляции решения, так что на это стоит обратить внимание.

Использование


Использование пакета Microsoft.Bcl.Async в среде Windows Phone 7.5/7.8 несильно отличается от async/await в .NET 4.5. Правда, всё же есть некоторые оговорки: например, статические функции класса Task из .NET 4.5 в пакете Bcl.Async перекочевали в класс TaskEx, а необходимые для поддержки асинхронности классы из пространства имён System.Runtime.CompilerServices — в Microsoft.Runtime.CompilerServices.

Версия Microsoft.Bcl.Async для Windows Phone 7.5/7.8 содержит все необходимые для async/await API, в то время, как версия для Windows Phone 8 только расширяет границы сознания имеющиеся возможности.
Поэтому я для себя решил, что в проектах Windows Phone 8 пакет Microsoft.Bcl.Async мне не нужен. Тем не менее, в оригинальном WP8 SDK отсутствуют асинхронные методы некоторых классов, например, WebRequest. И хотя Microsoft не предоставляет исходных кодов Bcl.Async, внутренности библиотек можно легко просмотреть любым декомпилятором. Так что я создал небольшой класс TaskAsyncExtensions в своём проекте, куда добавил некоторые методы расширения, например, такие:

public static Task<Stream> GetRequestStreamAsync(this WebRequest source)
{
    return Task.Factory.StartNew(
        () => Task<Stream>.Factory.FromAsync(source.BeginGetRequestStream, source.EndGetRequestStream, null),
        CancellationToken.None,
        TaskCreationOptions.None,
        TaskScheduler.Default)
               .Unwrap();
}

public static Task<WebResponse> GetResponseAsync(this WebRequest source)
{
    return Task.Factory.StartNew(
        () => Task<WebResponse>.Factory.FromAsync(source.BeginGetResponse, source.EndGetResponse, null),
        CancellationToken.None,
        TaskCreationOptions.None,
        TaskScheduler.Default)
               .Unwrap();
}

К слову сказать, идея с Task.Factory.StartNew(...).Unwrap() появилась именно в финальной версии пакета Microsoft.Bcl.Async: в RC-версии, вышедшей в конце января, эти методы возвращали просто Task.Factory.FromAsync(...). Может, кто-нибудь пояснит в комментариях, в чём принципиальное отличие?

Заключение


Всё это, на самом деле, позволяет использовать имеющиеся наработки с наименьшими «твиками» на разных платформах. Например, один из основных классов в моём приложении, работающих с сетью, содержит только один «твик» для кроссплатформенности:

#if WP7
    string requestParams = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(jParams));
#else
    string requestParams = await JsonConvert.SerializeObjectAsync(jParams);
#endif

Предвещая вопросы о директивах препроцессора и portable-библиотеках, скажу следующее: я стараюсь делать так, чтобы .XAP-пакеты моих приложений занимали как можно меньше места, а сами приложения использовали как можно меньше ссылок. Может, это бзик, хотя с размером пакетов объяснение простое — их качают по сотовой сети. Однако же в данном случае я вполне могу использовать Microsoft.Bcl.Async со всеми его зависимостями в проекте Windows Phone 7.x и не использовать его совсем в проекте Windows Phone 8. Мне так спокойнее.

Я очень надеюсь, что эта статья кому-то поможет и, может, даже станет откровением в плане существования Microsoft.Bcl.Async, а также я очень рассчитываю на то, что вы не станете пренебрегать такой замечательной возможностью, как async/await, и все приложения, загружающие данные из Интернета в процессе запуска, в скором времени канут в Лету. Спасибо за внимание!

Материалы:

Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

2

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • habrahabr.ru
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции