Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ПИ Программирование на С# _Хотов.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.22 Mб
Скачать
      1. Асинхронные методы, async и await

В .NET 4.5 во фреймворк были добавлены два новых ключевых слова async и await, цель которых - упростить написание асинхронного кода. Вместе с функциональностью задач Task они составляют основу новой модели асинхронного программирования в .NET, которая называется Task-based Asynchronous Pattern.

Ключевое слово async указывает, что метод или лямбда-выражение будет выполняться асинхронно. А оператор awaitпозволяет остановить текущий поток, пока не завершится работа метода, помеченного как async.

Эти операторы используются вместе для создания асинхронного метода. Такой метод, определенный с помощью модификатора async и содержащий одно или несколько выражений await, называется асинхронным методом.

Посмотрим на примере:

class Program

{

static void Main(string[] args)

{

DisplayResultAsync();

Console.ReadLine();

}

static async void DisplayResultAsync()

{

int num = 5;

int result = await FactorialAsync(num);

Thread.Sleep(3000);

Console.WriteLine("Факториал числа {0} равен {1}", num, result);

}

static Task<int> FactorialAsync(int x)

{

int result = 1;

return Task.Run(() =>

{

for (int i = 1; i <= x; i++)

{

result *= i;

}

return result;

});

}

}

Итак, здесь определен метод, возвращающий объект Task - задачу, которая выполняется асинхронно. И так так мы получаем факториал целого числа, то объект задачи типизирован типом int.

Сам факториал мы получаем в асинхронном методе DisplayResultAsync. Асинхронным он является потому, что он объявлен с модификатором async и содержит использование ключевого слова await.

По негласным правилам в названии асинхроннных методов принято использовать суффикс Async.

И так как метод FactorialAsync возвращает не просто число int, а объект асинхронной задачи Task<int>, то мы можем его вызвать с ключевым словом await, как в данном случае. Await-метод уже возвращает непосредственный результат.

И в методе Main мы вызываем этот асинхронный метод. Однако, как говорилось в теме про класс Task, если у нас асинхронная задача выполняется довольно приличное время, то мы можем не дождаться окончания ее выполнения и также щелкнуть на любую клавишу и выйти из программы. Чтобы в обязательном порядке дождаться окончания выполнения, нужно определить метод DisplayResultAsync() как задачу и у нее вызвать метод Wait:

static void Main(string[] args)

{

Task t = DisplayResultAsync();

t.Wait();

Console.ReadLine();

}

static async Task DisplayResultAsync()

{

int num = 5;

int result = await FactorialAsync(num);

Thread.Sleep(3000);

Console.WriteLine("Факториал числа {0} равен {1}", num, result);

}

Либо можно применить метод .GetAwaiter(), который остановит выполнение в вызывающем потоке, пока задача не завершится:

static void Main(string[] args)

{

DisplayResultAsync().GetAwaiter();

Console.WriteLine("Задача DisplayResultAsync завершена");

Console.ReadLine();

}

Также в данном примере мы можем также определить в качестве асинхронного метода и метод подсчета факториала:

static async Task<int> FactorialAsync(int x)

{

int result = 1;

return await Task.Run(() =>

{

for (int i = 1; i <= x; i++)

{

result *= i;

}

return result;

});

}

При определении асинхронных методов надо учитывать, что в качестве возвращаемого результата должен быть объект Task<T> или просто Task (если метод не возвращает результата, как DisplayResultAsync) или void.