начальных настроек в коде организуется цикл по файлам с асинхронным вызовом метода
ProcessFile
для каждого файла. Вызов метода
ProcessFile
помещен внутрь блока
try/catch
и ему передается объект
CancellationToken
. Если вызов
Cancel
выполняется на
CancellationTokenSource
(т.е. когда пользователь щелкает на кнопке Cancel), тогда генерируется исключение
OperationCanceledException
.
На заметку! Код
try/catch
может находиться где угодно в цепочке вызовов (как вскоре вы увидите). Размещать его при первом вызове или внутри самого асинхронного метода — вопрос личных предпочтений и нужд приложения.
(как и вызывающий код) на случай щелчка пользователем на кнопке Cancel.
Асинхронные потоки (нововведение в версии 8.0)
В версии C# 8.0 появилась возможность создания и потребления потоков данных (раскрываются в главе 20) асинхронным образом. Метод, который возвращает асинхронный поток данных:
• объявляется с модификатором
async
;
• возвращает реализацию
IAsyncEnumerable<T>
;
• содержит операторы
yield return
(рассматривались в главе 8) для возвращения последовательных элементов в асинхронном потоке данных.
Взгляните на приведенный далее пример:
public static async IAsyncEnumerable<int> GenerateSequence
{
for (int i = 0; i < 20; i++)
{
await Task.Delay(100);
yield return i;
}
}
Метод
GenerateSequence
объявлен как
async
, возвращает реализацию
IAsyncEnumerable<int>
и применяет
yield return
для возвращения целых чисел из последовательности. Чтобы вызывать этот метод, добавьте следующий код:
await foreach (var number in GenerateSequence)
{
Console.WriteLine(number);
}
Итоговые сведения о ключевых словах async и await
Настоящий раздел содержал много примеров; ниже перечислены ключевые моменты, которые в нем рассматривались.
• Методы (а также лямбда-выражения или анонимные методы) могут быть помечены ключевым словом
async
, что позволяет им работать в неблокирующей манере.
• Методы (а также лямбда-выражения или анонимные методы), помеченные ключевым словом
async
, будут выполняться синхронно до тех пор, пока не встретится ключевое слово
await
.
• Один метод
async
может иметь множество контекстов
await
.
• Когда встречается выражение
await
, вызывающий поток приостанавливается до тех пор, пока ожидаемая задача не завершится. Тем временем управление возвращается коду, вызвавшему метод.
• Ключевое слово
await
будет скрывать с глаз возвращаемый объект
Task
, что выглядит как прямой возврат лежащего в основе возвращаемого значения. Методы, не имеющие возвращаемого значения, просто возвращают
void
.
• Проверка параметров и другая обработка ошибок должна делаться в главной части метода с переносом фактической порции
async
в закрытую функцию.
• Для переменных, находящихся в стеке, объект
ValueTask
более эффективен, чем объект
Task
, который может стать причиной упаковки и распаковки.