Поделиться через


async (справочник по C#)

Модификатор async позволяет указать, что метод, лямбда-выражение или анонимный метод является асинхронным. Если этот модификатор используется в методе или выражении, они называются асинхронными методами. Ниже приводится пример асинхронного метода с именем ExampleMethodAsync:

public async Task<int> ExampleMethodAsync()
{
    //...
}

Если вы только начали заниматься асинхронным программированием или не понимаете, как в асинхронном методе используется оператор await для выполнения потенциально долгих операций без блокировки потока вызывающего объекта, ознакомьтесь с общими сведениями в статье Асинхронное программирование с использованием ключевых слов async и await. Следующий код размещается внутри асинхронного метода и вызывает метод HttpClient.GetStringAsync:

string contents = await httpClient.GetStringAsync(requestUrl);

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

Если метод, который изменяется ключевым словом async, не содержит выражения или оператора await, метод выполняется синхронно. Компилятор выводит предупреждения обо всех асинхронных методах, не содержащих операторы await, поскольку такая ситуация может указывать на ошибку. См. раздел Предупреждение компилятора (уровень 1) CS4014.

Ключевое слово async — это контекстно-зависимо ключевое слово, которое является ключевым словом, когда оно изменяет метод, лямбда-выражение или анонимный метод. Во всех других контекстах он интерпретируется как идентификатор.

Пример

В следующем примере показана структура и поток управления между обработчиком асинхронных событий StartButton_Click и асинхронным методом ExampleMethodAsync. В результате выполнения этого асинхронного метода возвращается число символов на веб-странице. Код подходит для приложения Windows Presentation Foundation (WPF) или приложения для Магазина Windows Presentation Foundation (WPF), которые создаются в Visual Studio; см. комментарии к коду для настройки приложения.

Этот код можно выполнить в Visual Studio как приложение Windows Presentation Foundation (WPF) или приложение Магазина Windows. Вам понадобятся элементы управления типа "Кнопка" (StartButton) и "Текстовое поле" (ResultsTextBox). Не забудьте задать имена и обработчик, чтобы получить код следующего вида:

<Button Content="Button" HorizontalAlignment="Left" Margin="88,77,0,0" VerticalAlignment="Top" Width="75"
        Click="StartButton_Click" Name="StartButton"/>
<TextBox HorizontalAlignment="Left" Height="137" Margin="88,140,0,0" TextWrapping="Wrap"
         Text="&lt;Enter a URL&gt;" VerticalAlignment="Top" Width="310" Name="ResultsTextBox"/>

Выполнение кода в виде приложения WPF:

  • Вставьте этот код в класс MainWindow в MainWindow.xaml.cs.
  • Добавьте ссылку на System.Net.Http.
  • Добавьте директиву using для System.Net.Http.

Выполнение кода в виде приложения Магазина Windows:

  • Вставьте этот код в класс MainPage в MainPage.xaml.cs.
  • Добавьте using директивы для System.Net.Http и System.Threading.Tasks.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // ExampleMethodAsync returns a Task<int>, which means that the method
    // eventually produces an int result. However, ExampleMethodAsync returns
    // the Task<int> value as soon as it reaches an await.
    ResultsTextBox.Text += "\n";

    try
    {
        int length = await ExampleMethodAsync();
        // Note that you could put "await ExampleMethodAsync()" in the next line where
        // "length" is, but due to when '+=' fetches the value of ResultsTextBox, you
        // would not see the global side effect of ExampleMethodAsync setting the text.
        ResultsTextBox.Text += String.Format("Length: {0:N0}\n", length);
    }
    catch (Exception)
    {
        // Process the exception if one occurs.
    }
}

public async Task<int> ExampleMethodAsync()
{
    var httpClient = new HttpClient();
    int exampleInt = (await httpClient.GetStringAsync("http://msdn.microsoft.com")).Length;
    ResultsTextBox.Text += "Preparing to finish ExampleMethodAsync.\n";
    // After the following return statement, any method that's awaiting
    // ExampleMethodAsync (in this case, StartButton_Click) can get the
    // integer result.
    return exampleInt;
}
// The example displays the following output:
// Preparing to finish ExampleMethodAsync.
// Length: 53292

Внимание

Дополнительные сведения о задачах и коде, который выполняется во время ожидания задачи, см. в разделе Асинхронное программирование с использованием ключевых слов async и await. Полный пример консоли, в котором используются похожие элементы, см. в разделе Обработка асинхронных задач по мере их завершения (C#).

Типы возвращаемых данных

Асинхронные методы могут иметь следующие типы возвращаемых значений:

  • Task
  • Task<TResult>
  • void. Методы async void обычно рекомендуются для кода, отличного от обработчиков событий, поскольку вызывающие объекты не могут await эти методы и должны реализовать другой механизм уведомления об успешном завершении или ошибках.
  • Любой тип, имеющий доступный GetAwaiter метод. Одной из таких реализаций является тип System.Threading.Tasks.ValueTask<TResult>. Доступ к нему осуществляется посредством пакета NuGet System.Threading.Tasks.Extensions.

Асинхронный метод не может объявлять параметры in, ref или out, а также иметь ссылочное возвращаемое значение, но он может вызывать методы с такими параметрами.

Task<TResult> указывается в качестве возвращаемого типа асинхронного метода, если оператор return метода задает операнд типа TResult. Класс Task используется при отсутствии содержательного значения, возвращаемого методом при его завершении. То есть вызов метода возвращает Task, однако когда Task завершен, любое выражение await, которое ожидает Task, возвращает значение void.

Возвращаемый тип void используется в основном для определения обработчиков событий, которые требуют этого возвращаемого типа. Вызывающий объект асинхронного метода, возвращающего void, не может ожидать его и перехватывать создаваемые методом исключения.

Вы возвращаете другой тип, как правило, тип значения, который имеет GetAwaiter метод для минимизации выделения памяти в критически важных для производительности разделах кода.

Дополнительные сведения и примеры см. в разделе Асинхронные типы возвращаемых значений.

См. также