- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
Знакомство с ключевыми словами async и await языка C# (обновление в версиях 7.1, 9.0)
Ключевое слово async языка C# применяется для указания на то, что метод, лямбда-выражение или анонимный метод должен вызываться в асинхронной манере автоматически. Да, это правда. Благодаря простой пометке метода модификатором async среда .NET Core Runtime будет создавать новый поток выполнения для обработки текущей задачи. Более того, при вызове метода async ключевое слово await будет автоматически приостанавливать текущий поток до тех пор, пока задача не завершится, давая возможность вызывающему потоку продолжить свою работу.
В целях иллюстрации создайте новый проект консольного приложения по имени FunWithCSharpAsync и импортируйте в файл Program.cs пространства имен System.Threading, System.Threading.Task и System.Collections.Generic. Добавьте метод DoWork(), который заставляет вызывающий поток ожидать пять секунд. Ниже показан код:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
Console.WriteLine(" Fun With Async ===>");
Console.WriteLine(DoWork());
Console.WriteLine("Completed");
Console.ReadLine();
static string DoWork()
{
Thread.Sleep(5_000);
return "Done with work!";
}
Вам известно, что после запуска программы придется ожидать пять секунд, прежде чем сможет произойти что-то еще. В случае графического приложения весь пользовательский интерфейс был бы заблокирован до тех пор, пока работа не завершится.
Если бы мы решили прибегнуть к одному из описанных ранее приемов, чтобы сделать приложение более отзывчивым, тогда пришлось бы немало потрудиться. Тем не менее, начиная с версии .NET 4.5, можно написать следующий код С#:
...
string message = await DoWorkAsync();
Console.WriteLine(message);
...
static string DoWork()
{
Thread.Sleep(5_000);
return "Done with work!";
}
static async Task<string> DoWorkAsync()
{
return await Task.Run(() =>
{
Thread.Sleep(5_000);
return "Done with work!";
});
}
Если вы используете в качестве точки входа метод Main() (вместо операторов верхнего уровня), тогда должны пометить метод с помощью ключевого слова async, появившегося в версии C# 7.1:
static async Task Main(string[] args)
{
...
string message = await DoWorkAsync();
Conole.WriteLine(message);
...
}
На заметку! Возможность декорирования метода Main() посредством async — нововведение, появившееся в версии C# 7.1. Операторы верхнего уровня в версии C# 9.0 являются неявно асинхронными.
Обратите внимание на ключевое слово await перед именем метода, который будет вызван в неблокирующей манере. Это важно: если метод декорируется ключевым словом async, но не имеет хотя бы одного внутреннего вызова метода с использованием await, то получится синхронный вызов (на самом деле компилятор выдаст соответствующее предупреждение).
Кроме того, вы должны применять класс Task из пространства имен System.Threading.Tasks для переделки методов Main() (если вы используете Main()) и DoWork() (последний добавляется как DoWorkAsync()). По существу вместо возвращения просто специфического значения (объекта string в текущем примере) возвращается объект Task<T>, где обобщенный параметр типа Т представляет собой действительное возвращаемое значение.
Реализация метода DoWorkAsync() теперь напрямую возвращает объект Task<T>, который является возвращаемым значением Task.Run(). Метод Run() принимает делегат Func<> или Action<> и, как вам уже известно, для простоты здесь можно использовать лямбда-выражение. В целом новая версия DoWorkAsync() может быть описана следующим образом.
При вызове запускается новая задача, которая заставляет вызывающий поток уснуть на пять секунд. После завершения вызывающий поток предоставляет строковое возвращаемое значение. Эта строка помещается в новый объект Task<string> и возвращается вызывающему коду.
Благодаря новой реализации метода DoWorkAsync() мы можем получить некоторое представление о подлинной роли ключевого слова await. Оно всегда будет модифицировать метод, который возвращает объект Task. Когда поток выполнения достигает await, вызывающий поток приостанавливается до тех пор, пока вызов не будет завершен. Запустив эту версию приложения, вы обнаружите, что сообщение Completed отображается перед сообщением Done with work! В случае графического приложения можно было бы продолжать работу с пользовательским интерфейсом одновременно с выполнением метода DoWorkAsync().
Класс SynchronizationContext и async/await
Тип SynchronizationContext формально определен как базовый класс, который предоставляет свободный от потоков контекст баз синхронизации. Хотя такое первоначальное определение не особо информативно, в официальной документации указаны следующие сведения.
Цель модели синхронизации, реализуемой классом SynchronizationContext, заключается в том, чтобы позволить внутренним асинхронным/синхронным операциям общеязыковой исполняющей среды вести себя надлежащим образом с различными моделями синхронизации.
Наряду с тем, что вам уже известно о многопоточности, такое заявление проливает свет на этот вопрос. Вспомните, что приложения с графическим пользовательским интерфейсом (Windows Forms, WPF) не разрешают прямой доступ к элементам управления из вторичных потоков, а требуют делегирования доступа. Вы уже видели объект Dispatcher в примере приложения WPF. В консольных приложениях, которые не используют WPF, это ограничение отсутствует. Речь идет о разных моделях синхронизации. С учетом всего сказанного давайте рассмотрим класс SynchronizationContext.
Класс SynchonizationContext является типом, предоставляющим виртуальный метод отправки, который принимает делегат, предназначенный для выполнения асинхронным образом. В результате инфраструктуры получают шаблон для надлежащей обработки асинхронных запросов (диспетчеризация для приложений WPF/Windows Forms, прямое выполнение для приложений без графического пользовательского интерфейса и т.д.). Он предлагает способ постановки в очередь единицы работы в контексте и подсчета асинхронных операций, ожидающих выполнения.
Как обсуждалось ранее, когда делегат помещается в очередь для асинхронного выполнения, он планируется к запуску в отдельном потоке, что обрабатывается средой .NET Core Runtime. Задача обычно решается с помощью управляемого пула потоков .NET Core Runtime, но может быть построена и специальная реализация.
Хотя такими связующими действиями можно управлять вручную в коде, шаблон async/await делает большую часть трудной работы. В случае применения await к асинхронному методу задействуются реализации SynchronizationContext и TaskScheduler целевой инфраструктуры. Например, если вы используете