С выходом версии .NET 4.5 в языке программирования C# появились два новых ключевых слова, которые дополнительно упрощают процесс написания асинхронного кода. По контрасту со всеми примерами, показанными ранее в главе, когда применяются ключевые слова async
await, компилятор будет самостоятельно генерировать большой объем кода, связанного с потоками, с использованием многочисленных членов из пространств имен System.Threading и System.Threading.Tasks.Знакомство с ключевыми словами async и await языка C# (обновление в версиях 7.1, 9.0)
Ключевое слово async
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
{
return await
{
Thread.Sleep(5_000);
return "Done with work!";
});
}
Если вы используете в качестве точки входа метод Main()
async, появившегося в версии C# 7.1:static async
{
...
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, где обобщенный параметр типа Т представляет собой действительное возвращаемое значение.Реализация метода DoWorkAsync()
Task, который является возвращаемым значением Task.Run(). Метод Run() принимает делегат Func<> или Action<> и, как вам уже известно, для простоты здесь можно использовать лямбда-выражение. В целом новая версия DoWorkAsync() может быть описана следующим образом.