«Как перестать отлаживать асинхронные вызовы и начать жить»FDConfАсинхронность в Javascript больше не страшна. Классические триллеры вроде
«Callback Hell» и «Pyramid of Doom» потеряли свою актуальность настолько,что даже Java-программисты перестали пугать ими невинных джуниоров.
Всё благодаря паттернам и библиотекам. Streams, Promises, Async-Await и другие изменили наш код. Теперь он прекрасен.
Пока ещё вымысел? Поговорим о том, как сделать эту картину реальностью. Об основных практиках асинхронного программирования.
Принципах их работы,отличиях и сценариях использования.
Service Discovery. More that it seemsAleksandr TarasovThere is a problem of finding the best instance of a service in distributed systems with dynamic configuration. Nowadays, there are many products for the configuration storage and service discovery. It should be mentioned at least Netflix Eureka, Consul, etc or good old Zookeeper. These products can keep and give configuration, manage service instances lifecycle and some of them even can be as dynamic DNS service. But main question is not about what instance may be called at the certain time. It is about what instance is better for call? This means that smart load balancing top on service discovery is required. Spring Cloud project allows to integrate these products to your project and provides powerful solutions for typical problems, that make cloud native services developing easier. This talk will review the internal structure of SpringCloud implementation of Client-Side Service Discovery and Client Load Balancing patterns. It also will include specific details of concrete implementations with examples from official libraries and the author’s own library.
Превышаем скоростные лимиты с Angular 2Oleksii Okhrymenko* Почему Angular 2 такой быстрый и как его ускорить еще сильнее?
* Как работает Change Detection механизм и как им управлять?
* Зачем нам Zone.js и Функциональное Реактивное Программирование?
* Как работать с Redux и Mobx в Angular 2 и что можно от этого выиграть?
Об этом и ряде других вещей вы узнаете из этого доклада.
Производительность open source решенийVladimir SitnikovОбщедоступные программы и библиотеки подкупают своей бесплатностью. Если же исходный код открыт, то все сразу думают, что «умные дядьки уже исправили всё, что нужно». На практике же оказывается, что грабли разложены там, где их мало кто ждёт. Тормозит всё, кроме, разве что, самой java. В докладе мы рассмотрим примеры проблем производительности при использовании таких библиотек как Wildfly, Spring, HornetQ, pgjdbc.
Например, оказывается, что spring.getBean тормозит, а в комбинации с autoproxy вообще может занимать до 50% времени приложения. Cglib мешает работе garbage collector’а в попытках проксировать Object#finalize, а HornetQ внезапно притормаживает отправку JMS, что запросто приводит к 5-и секундным задержкам на одно сообщение. Узнаем как их опознать и обезвредить.
Михаил Давыдов - JavaScript. АсинхронностьYandexАсинхронность стала неотъемлемой частью как клиент-сайда, так и бек-энда. Будут рассмотрены основные паттерны и библиотеки, позволяющие сделать код читаемым и поддерживаемым.
Реактивный двигатель вашего Android приложенияMatvey MalkovПрезентация, объясняющая концепцию реактивных потоков с использованием Android SDK и RxJavа. Рассчитано на программистов с любым стажем, которые жеалют начать использовать эту концепцию в своих программах.
Реактивные потоки -- это круто.
Эволюционный дизайн. Joker Students Day 2016Кирилл ТолкачёвСлучалось ли, что вы видели (чужой) код и хотели все переписать? Бывало такое, что вы не могли понять, почему кем-то было принято конкретное решение, не другое? Хотели ли вы воскликнуть:«А я бы сделал еще круче!»?
Если вы задумывались об этом, вам будет интересно послушать историю о том, как эти вопросы возникали у Александра и Кирилла и как они решались в условиях большой компании.
Разработчики расскажут, как в самом начале пути вытаскивали шашки и шли в атаку на проблемную архитектуру. Но все оказалось не так просто, и по мере погружения в проект парни стали понимать, что архитектура большой системы — компромисс между различными подходами и решениями, инновациями и легаси (наследованным кодом), централизацией и децентрализацией компонентов. Докладчики наработали очень много опыта в решении архитектурных задач и поделятся опытом и выработанными принципами, которых придерживаются в настоящее время.
Во время доклада будут обсуждаться непростые вопросы, возникающие при принятии решений о том, как будет жить и эволюционировать система.
Вместе со слушателями Александр и Кирилл проделают упражнение по созданию «таблицы технологий» и её эволюции. Также они покажут, насколько важно инженерное решение на любой из стадий развития системы.
Пользователь точно оценит! Повышение производительности мобильных приложений ...OnticoРасскажем о методиках создания производительных приложений, опираясь на собственный многолетний опыт проб и ошибок:
• использование инструментов отладки (работа с Hierarchy Viewer; поиск и устранение overdraw; профилирование методов; поиск утечек памяти);
• написание производительного кода;
• создание верстки, повышающей скорость работы приложений;
• создание требований к дизайну интерфейсов и API с оглядкой на производительность;
• использование аналитики для логирования и отладки багов.
Android-приложения Superjob:
• 3 приложения в Google Play для B2C и B2B-аудиторий;
• более 1 млн. пользователей;
• в числе лучших российских приложений по мнению Google Play.
Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...DevGAMM ConferenceВ докладе Антон расскажет о транзакционном фреймворке, на котором построен новый проект студии Pushkin: батлер с асинхронным мультиплеером, синхронизацией состояния между устройствами, минимальными требованиями к сети и защитой от читеров.
"Пиринговый веб на JavaScript"FDConf"В последнее время тема пиринговых технологий становится очень популярной. Уже не первый день работают такие проекты как криптовалюта Bitcoin, микроблоги Twister и мессенджер Tox. Теперь дошло дело и до децентрализованного веба.
Будет рассказано про общую схему работы сети, о работе с криптографией на JavaScript, о создании приложений на JavaScript без использования центральных серверов."
How to build solid CI-CD pipeline / Илья Беда (beda.software)OnticoРИТ++ 2017, Root Conf
Зал Конгресс-холл, 6 июня, 15:00
Тезисы:
http://rootconf.ru/2017/abstracts/2551.html
На основе своего опыта работы в консалтинге я расскажу, как избавить разработчиков от рутинных задач и как сэкономить на ресурсах команды с помощью правильно настроенного CI-CD pipeline.
Единствено верный способ упаковки приложений - это Docker-контейнеры, благодаря этому способу вы сможете унифицировать процесс деплоя. Нужно деплоить приложения с помощью Ansible-плейбука, запакованного в Docker-контейнер, это снижает требования к окружению CI-ранера. Вам нужен только Docker.
...
Практика Lock-free. RealTime-серверPlatonov SergeyВ докладе пойдёт речь о практическом применении lock-free структур и алгоритмов, которые используются в RealTime-Поиске в Яндексе. Из-за сложности теоретических исследований по lock-free и оторванности от практики часто создаётся впечатление, что это просто развлечение для знатоков computer science и не может быть использовано в реальном проекте. Будут рассмотрены проблемы традиционного подхода к lock-free и показано, как взглянув по новому на всю идею lock-free, добиться максимальной производительности, невозможной при использовании блокировок.
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»FDConfДоклад о том, зачем нужен CI, как он интегрируется в процесс разработки. В докладе есть небольшое демо о весьма известном cloud-based CI сервисе Travis-CI. В процессе демо будет «поломан» билд и затем сразу же починен. Весьма показательно в том плане, что это доказывает простоту всей технологии.
Service Discovery. More that it seemsAleksandr TarasovThere is a problem of finding the best instance of a service in distributed systems with dynamic configuration. Nowadays, there are many products for the configuration storage and service discovery. It should be mentioned at least Netflix Eureka, Consul, etc or good old Zookeeper. These products can keep and give configuration, manage service instances lifecycle and some of them even can be as dynamic DNS service. But main question is not about what instance may be called at the certain time. It is about what instance is better for call? This means that smart load balancing top on service discovery is required. Spring Cloud project allows to integrate these products to your project and provides powerful solutions for typical problems, that make cloud native services developing easier. This talk will review the internal structure of SpringCloud implementation of Client-Side Service Discovery and Client Load Balancing patterns. It also will include specific details of concrete implementations with examples from official libraries and the author’s own library.
Превышаем скоростные лимиты с Angular 2Oleksii Okhrymenko* Почему Angular 2 такой быстрый и как его ускорить еще сильнее?
* Как работает Change Detection механизм и как им управлять?
* Зачем нам Zone.js и Функциональное Реактивное Программирование?
* Как работать с Redux и Mobx в Angular 2 и что можно от этого выиграть?
Об этом и ряде других вещей вы узнаете из этого доклада.
Производительность open source решенийVladimir SitnikovОбщедоступные программы и библиотеки подкупают своей бесплатностью. Если же исходный код открыт, то все сразу думают, что «умные дядьки уже исправили всё, что нужно». На практике же оказывается, что грабли разложены там, где их мало кто ждёт. Тормозит всё, кроме, разве что, самой java. В докладе мы рассмотрим примеры проблем производительности при использовании таких библиотек как Wildfly, Spring, HornetQ, pgjdbc.
Например, оказывается, что spring.getBean тормозит, а в комбинации с autoproxy вообще может занимать до 50% времени приложения. Cglib мешает работе garbage collector’а в попытках проксировать Object#finalize, а HornetQ внезапно притормаживает отправку JMS, что запросто приводит к 5-и секундным задержкам на одно сообщение. Узнаем как их опознать и обезвредить.
Михаил Давыдов - JavaScript. АсинхронностьYandexАсинхронность стала неотъемлемой частью как клиент-сайда, так и бек-энда. Будут рассмотрены основные паттерны и библиотеки, позволяющие сделать код читаемым и поддерживаемым.
Реактивный двигатель вашего Android приложенияMatvey MalkovПрезентация, объясняющая концепцию реактивных потоков с использованием Android SDK и RxJavа. Рассчитано на программистов с любым стажем, которые жеалют начать использовать эту концепцию в своих программах.
Реактивные потоки -- это круто.
Эволюционный дизайн. Joker Students Day 2016Кирилл ТолкачёвСлучалось ли, что вы видели (чужой) код и хотели все переписать? Бывало такое, что вы не могли понять, почему кем-то было принято конкретное решение, не другое? Хотели ли вы воскликнуть:«А я бы сделал еще круче!»?
Если вы задумывались об этом, вам будет интересно послушать историю о том, как эти вопросы возникали у Александра и Кирилла и как они решались в условиях большой компании.
Разработчики расскажут, как в самом начале пути вытаскивали шашки и шли в атаку на проблемную архитектуру. Но все оказалось не так просто, и по мере погружения в проект парни стали понимать, что архитектура большой системы — компромисс между различными подходами и решениями, инновациями и легаси (наследованным кодом), централизацией и децентрализацией компонентов. Докладчики наработали очень много опыта в решении архитектурных задач и поделятся опытом и выработанными принципами, которых придерживаются в настоящее время.
Во время доклада будут обсуждаться непростые вопросы, возникающие при принятии решений о том, как будет жить и эволюционировать система.
Вместе со слушателями Александр и Кирилл проделают упражнение по созданию «таблицы технологий» и её эволюции. Также они покажут, насколько важно инженерное решение на любой из стадий развития системы.
Пользователь точно оценит! Повышение производительности мобильных приложений ...OnticoРасскажем о методиках создания производительных приложений, опираясь на собственный многолетний опыт проб и ошибок:
• использование инструментов отладки (работа с Hierarchy Viewer; поиск и устранение overdraw; профилирование методов; поиск утечек памяти);
• написание производительного кода;
• создание верстки, повышающей скорость работы приложений;
• создание требований к дизайну интерфейсов и API с оглядкой на производительность;
• использование аналитики для логирования и отладки багов.
Android-приложения Superjob:
• 3 приложения в Google Play для B2C и B2B-аудиторий;
• более 1 млн. пользователей;
• в числе лучших российских приложений по мнению Google Play.
Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...DevGAMM ConferenceВ докладе Антон расскажет о транзакционном фреймворке, на котором построен новый проект студии Pushkin: батлер с асинхронным мультиплеером, синхронизацией состояния между устройствами, минимальными требованиями к сети и защитой от читеров.
"Пиринговый веб на JavaScript"FDConf"В последнее время тема пиринговых технологий становится очень популярной. Уже не первый день работают такие проекты как криптовалюта Bitcoin, микроблоги Twister и мессенджер Tox. Теперь дошло дело и до децентрализованного веба.
Будет рассказано про общую схему работы сети, о работе с криптографией на JavaScript, о создании приложений на JavaScript без использования центральных серверов."
How to build solid CI-CD pipeline / Илья Беда (beda.software)OnticoРИТ++ 2017, Root Conf
Зал Конгресс-холл, 6 июня, 15:00
Тезисы:
http://rootconf.ru/2017/abstracts/2551.html
На основе своего опыта работы в консалтинге я расскажу, как избавить разработчиков от рутинных задач и как сэкономить на ресурсах команды с помощью правильно настроенного CI-CD pipeline.
Единствено верный способ упаковки приложений - это Docker-контейнеры, благодаря этому способу вы сможете унифицировать процесс деплоя. Нужно деплоить приложения с помощью Ansible-плейбука, запакованного в Docker-контейнер, это снижает требования к окружению CI-ранера. Вам нужен только Docker.
...
Практика Lock-free. RealTime-серверPlatonov SergeyВ докладе пойдёт речь о практическом применении lock-free структур и алгоритмов, которые используются в RealTime-Поиске в Яндексе. Из-за сложности теоретических исследований по lock-free и оторванности от практики часто создаётся впечатление, что это просто развлечение для знатоков computer science и не может быть использовано в реальном проекте. Будут рассмотрены проблемы традиционного подхода к lock-free и показано, как взглянув по новому на всю идею lock-free, добиться максимальной производительности, невозможной при использовании блокировок.
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»FDConfДоклад о том, зачем нужен CI, как он интегрируется в процесс разработки. В докладе есть небольшое демо о весьма известном cloud-based CI сервисе Travis-CI. В процессе демо будет «поломан» билд и затем сразу же починен. Весьма показательно в том плане, что это доказывает простоту всей технологии.
Асинхронность и сопрограммыPlatonov SergeyКак показывает практика, повсеместное применение классического, основанного на callback’ах подхода к асинхронному программированию обычно оказывается неудобным. Для упрощения написания и поддержки сложного асинхронного кода можно использовать иной подход — с использованием сопрограмм. Он значительно сокращает объём и сложность кода, превращая код из асинхронного в синхронный.
Григорий Демченко — Асинхронное программирование и сопрограммыYandexКак показывает практика, повсеместное применение классического, основанного на callback’ах подхода к асинхронному программированию обычно оказывается неудобным. Для упрощения написания и поддержки сложного асинхронного кода можно использовать иной подход — с использованием сопрограмм. Он значительно сокращает объём и сложность кода, а также существенно упрощает реализацию нетривиальных сценариев, связанных с отменой вычислений и таймаутами операций.
Asynchrony and coroutinescorehard_byКак показывает практика, применение классического, основанного на callback’ах подхода к асинхронному программированию обычно оказывается неудобным. Для упрощения написания и поддержки сложного асинхронного кода можно использовать иной подход, основанный на прозрачном использованием сопрограмм. Он значительно сокращает объём и сложность кода, превращая его в понятный, легко читаемый и структурируемый код.
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полнойОмские ИТ-субботникиТестирование фронтенда - непростая задача. Mocha - один из подходов к ее решению.
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Andrey RebrovКак-то так происходит, что “на 10 девчонок по статистике 9 ребят”, а точнее на группу из 5-7 разработчиков – 1 тестировщик. Или его нет совсем. Так что очень часто приходится и код писать, и тестировать, а дата релиза все ближе и ближе.
В тех случаях, когда мы пишем веб-приложение, помочь в нашей нелегкой судьбе может бодрящий микс из Selenium и TestNG... Как это сделали мы, какие потом получили выводы и результаты — все это я и хочу рассказать и показать
async/await: собираем граблиAndrey ChasovskikhВ докладе разбираются основные заблуждения и ошибки в использовании async/await, а также дается список полезных советов по написанию асинхронного кода.
4. Асинхронный метод (.NET 4.5)
public static async Task MainAsync()
{
string googleResult = await new HttpClient().GetStringAsync("https://google.com/");
Console.WriteLine($"Google loaded! Content length: {googleResult.Length}");
string yandexResult = await new HttpClient().GetStringAsync("https://yandex.ru");
Console.WriteLine($"Yandex loaded! Content length: {yandexResult.Length}");
}
5. Асинхронная модель на основе задач (TAP)
● Асинхронная модель на основе задач (Task-based Asynchronous Pattern, TAP).
● TAP основан на трех “китах” - типах Task и Task<T>, операторе await и маркере async.
● Task и Task<T> - описывают асинхронную операцию, ее результат (если есть) и callback-метод.
public class Task<TResult> : Task
{
public TResult Result { get; internal set; }
public Task<TNewResult> ContinueWith<TNewResult>(
Func<Task<TResult>, TNewResult> continuationFunction
);
}
● Маркер async применяется к методу, который возвращает Task, Task<T> или void, и когда в
теле метода используется оператор await.
● Оператор await нужен для объединения последовательности асинхронных операций в одну. Этот
оператор принимает на вход объект, описывающий асинхронную операцию, и так переписывает
код, что бы все, что следует после выражения с await, преобразовывалось в замыкание и было
аргументом метода ContinueWith объекта к которому применяется await.
6. Преобразованный код
[DebuggerStepThrough, AsyncStateMachine(typeof(Program.<MainAsync>d__1))]
public static void MainAsync()
{
Program.<MainAsync>d__1 <MainAsync>d__ = new Program.<MainAsync>d__1();
<MainAsync>d__.<>t__builder = AsyncVoidMethodBuilder.Create();
<MainAsync>d__.<>1__state = -1;
AsyncVoidMethodBuilder <>t__builder = <MainAsync>d__.<>t__builder;
<>t__builder.Start<Program.<MainAsync>d__1>(ref <MainAsync>d__);
}
8. Как работает async/await
private async Task LoadContentAsync(string url1, string url2)
{
if (url1 == null) throw new ArgumentNullException(nameof(url1));
if (url2 == null) throw new ArgumentNullException(nameof(url2));
string googleResult = await new HttpClient().GetStringAsync(url1); // 1
Console.WriteLine($"Url1 loaded! Content length: {googleResult.Length}");
string yandexResult = await new HttpClient().GetStringAsync(url2); // 2
Console.WriteLine($"Url2 loaded! Content length: {yandexResult.Length}");
}
● Часть, предшествующая “1” будет выполнена синхронно
● Затем в строке “1” будет запущена асинхронная операция, которой в качестве callback-а будет передан
оставшийся код метода. В этот момент поток, в котором выполнялся метод, будет возвращен в пул потоков
● После того, как операция “1” завершит работу, из пула будет извлечен поток, в нем будет вызван переданный
callback, и метод продолжит выполнение синхронно
● Затем в строке “2” будет запущена асинхронная операция, которой в качестве callback-а будет передан
оставшийся код метода. В этот момент поток, в котором выполнялся метод, будет возвращен в пул потоков
● После того, как операция “1” завершит работу, из пула потоков будет извлечен поток, в нем будет вызван
переданный callback, и метод продолжит выполнение
9. Когда использовать async/await
● в толстых клиентах (WPF, Xamarin), когда тяжелые операции запускаются асинхронно, не занимая UI поток
private async void btnRead_Click(object sender, EventArgs e)
{
btnRead.Enabled = false;
Content = await sr.ReadToEndAsync();
btnRead.Enabled = true;
}
Флаг Enabled в обоих случаях устанавливается UI-потоком. Раньше необходимо было писать так:
if (btnRead.InvokeRequired)
{
btnRead.Invoke((Action)(() => btnRead.Enabled = false));
}
else
{
btnRead.Enabled = false;
}
● в веб-приложениях (ASP.NET) для более эффективного использования потоков.
public class FileController
{
public async Task<string> GetFileAsync()
{
return await ReadFileAsync();
}
}
10. async/await в ASP.NET
Когда поступает запрос, ASP.NET берет один из потоков в своем пуле и закрепляет запрос за ним. Синхронный вызов внешнего
ресурса блокирует поток запроса, пока вызванный внешний ресурс не вернет управление.
При поступлении запроса в тот момент, когда все потоки из пула заняты, он будет вынужден ждать появления свободного потока,
прежде чем начнется его обработка, но запрос уже находится в системе. Его таймер тикает, и есть опасность возникновения HTTP
Error 503 (Service unavailable).
В случае асинхронного обработчика, когда поступает запрос, ASP.NET берет один из потоков в своем пуле и закрепляет его за
этим запросом. На этот раз обработчик вызовет внешний ресурс асинхронно. После этого поток запроса возвращается в пул до
тех пор, пока не произойдет возврат из вызова внешнего ресурса.
11. Task.ConfigureAwait(bool)
● Сообщает CLR, нужно ли при запуске асинхронной операции захватывать текущий контекст синхронизации или нет
var content = await ReadFileAsync().ConfigureAwait(false);
● Если после выполнения асинхронной операции необходимо продолжить выполнение в том же потоке, из которого
эта операция была запущена, то необходимо запускать операцию с параметром ConfigureAwait(true), либо вовсе
без ConfigureAwait.
Console.WriteLine($"ThreadId before: {Thread.CurrentThread.ManagedThreadId}");
var content = await new HttpClient().GetStringAsync("https://google.com");
Console.WriteLine($"ThreadId after: {Thread.CurrentThread.ManagedThreadId}");
Вывод:
ThreadId before: 2
ThreadId after: 2
● Если вернуться можно в любой поток, то необходимо использовать ConfigureAwait(false).
Console.WriteLine($"ThreadId before: {Thread.CurrentThread.ManagedThreadId}");
var content = await new HttpClient().GetStringAsync("https://google.com").ConfigureAwait(false);
Console.WriteLine($"ThreadId after: {Thread.CurrentThread.ManagedThreadId}");
Вывод:
ThreadId before: 2
ThreadId after: 9
12. Task.ConfigureAwait(bool) часть 2
● ConfigureAwait настраивает только “свою” асинхронную операцию
private async void btnRead_Click(object sender, EventArgs e)
{
var content = await GetContentAsync(); // 1
lbl_Content.Text = content;
}
private async Task<string> GetContentAsync()
{
var contentFromDb = await LoadFromDatabaseAsync().ConfigureAwait(false); // 2
return contentFromDb;
}
● При создании библиотек следует всегда использовать ConfigureAwait(false) за исключением случаев, когда эта
библиотека работает с UI или контекстом ASP.NET. Использование ConfigureAwait(false) дает ощутимый рост
производительности.
13. Асинхронная синхронность и наоборот
● Библиотека предоставляет несколько статических методов класса Task, предназначенных для создания Task’ов из
результатов синхронных вызовов - Task.FromResult, Task.FromException, Task.CompletedTask
static Task<string> SomeAsyncFunction()
{
string result = SomeSyncFunction();
return Task.FromResult(result);
}
static string SomeSyncFunction() => “string”
● Вызывать асинхронные методы из синхронных не рекомендуется, но если очень нужно, то можно использовать
Task.GetAwaiter().GetResult()
string content = new HttpClient().GetStringAsync("https://google.com").ConfigureAwait(false).GetAwaiter().GetResult();
string content = new HttpClient().GetStringAsync("https://google.com").ConfigureAwait(false).Result;
14. Соглашения
● Асинхронные методы должны всегда возвращать Task или Task<TResult> с единственным исключением -
обработчики событий могут возвращать void
○ private async void btnRead_Click(object sender, EventArgs e)
● Асинхронные методы имеют суффикс Async после имени операции
○ GetStreamAsync
● Если класс уже содержит метод с суффиксом Async, то вместо этого добавляется суффикс TaskAsync
○ GetStreamTaskAsync
● Параметры асинхронного метода должны соответствовать параметрам его синхронного аналога и должны
предоставляться в том же порядке.
○ public int Read(byte[] buffer,int offset,int count)
○ public Task<int> ReadAsync(byte[] buffer, int offset, int count)
● Out и ref параметры не поддерживаются, и должны возвращаться как часть результата TResult
○ public void GetTwoMaxValues(out int max1, out int max2)
○ public Task<(int max1, int max2)> GetTwoMaxValuesAsync()
● Если операция позволяет выполнить отмену, она предоставляет перезагрузку асинхронного метода, принимающую
токен отмены - параметр с именем cancellationToken.
○ public Task<int> ReadAsync(byte[] buffer, int offset, int count)
○ public Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
15. Отмена асинхронной операции
● Для проверки факта отмены можно либо обращаться к свойству IsCancellationRequested, либо вызывать метод
ThrowIfCancellationRequested класса CancellationToken.
public static async Task FooAsync(CancellationToken cancellationToken)
{
while (true)
{
if (cancellationToken.IsCancellationRequested)
break;
// cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(1000);
}
}
● Для отмены асинхронной операции перед ее вызовом создается объект CancellationTokenSource и в момент, когда
требуется отмена, вызывается его метод Cancel
public static async Task CallerAsync(CancellationToken cancellationToken)
{
CancellationTokenSource cts = new CancellationTokenSource();
await FooAsync(cts.Token);
cts.Cancel();
}
● Для вызова метода с “фиктивным” токеном отмены ему следует передать CancellationToken.None
await FooAsync(CancellationToken.None);
16. Отчет о ходе выполнения
● Для некоторых асинхронных операций имеет смысл предоставлять уведомления о ходе их выполнения, для этого
используется интерфейс IProgress<T>, который передается ей в качестве параметра
public interface IProgress<in T>
{
void Report(T value);
}
public static async Task FooAsync(IProgress<int> progress)
{
for (int i = 0; i < 100; ++i)
{
if (i % 10 == 0) progress?.Report(i);
await Task.Delay(1000);
}
}
● Операция должна допускать значение null - в этом случае о ходе выполнения не сообщается.
● .NET Framework предоставляет одну реализацию - Progress<T>, который при вызове Report использует контекст
синхронизации, активный в момент его создания. Это позволяет, например, безопасно обновлять элементы UI
public async void Button1_Click(object sender, EventArgs args)
{
var progress = new Progress<int>(value =>
{
label2.Text = value.ToString();
});
await FooAsync(progress);
}
17. Await’ить или Task’овать
public static async Task CallerAsyncAsync()
{
var task = SomeAsyncFunction(null); // 1
Console.WriteLine("ByndyuSoft are the best!");
await task; // 2
}
● Вариант с возвратом Task
static Task<string> SomeAsyncFunction(string uri)
{
if (uri == null) throw new ArgumentNullException(nameof(uri));
return new HttpClient().GetStringAsync(uri);
}
Исключение будет возбуждено строке “1”
● Вариант с await
static async Task<string> SomeAsyncFunction(string uri)
{
if (uri == null) throw new ArgumentNullException(nameof(uri));
return await new HttpClient().GetStringAsync(uri);
}
Исключение будет возбуждено строке “2”