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

Модификатор async позволяет указать, что метод, лямбда-выражение или анонимный метод является асинхронным.Use the async modifier to specify that a method, lambda expression, or anonymous method is asynchronous. Если этот модификатор используется в методе или выражении, они называются асинхронными методами.If you use this modifier on a method or expression, it's referred to as an async method. Ниже приводится пример асинхронного метода с именем ExampleMethodAsync:The following example defines an async method named ExampleMethodAsync:

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

Если вы только начали заниматься асинхронным программированием или не понимаете, как в асинхронном методе используется ключевое слово await для выполнения потенциально долгой работы без блокировки потока вызывающего объекта, ознакомьтесь с общими сведениями в статье Асинхронное программирование с использованием ключевых слов Async и Await.If you're new to asynchronous programming or do not understand how an async method uses the await keyword to do potentially long-running work without blocking the caller’s thread, read the introduction in Asynchronous Programming with async and await. Следующий код размещается внутри асинхронного метода и вызывает метод HttpClient.GetStringAsync:The following code is found inside an async method and calls the HttpClient.GetStringAsync method:

string contents = await httpClient.GetStringAsync(requestUrl);  

Асинхронный метод выполняется синхронным образом до тех пор, пока не будет достигнуто первое выражение await, после чего метод приостанавливается, пока не будет завершена ожидаемая задача.An async method runs synchronously until it reaches its first await expression, at which point the method is suspended until the awaited task is complete. В то же время управление возвращается в вызывающий объект метода, как показано в примере в следующем разделе.In the meantime, control returns to the caller of the method, as the example in the next section shows.

Если метод, который изменяется ключевым словом async, не содержит выражения или оператора await, метод выполняется синхронно.If the method that the async keyword modifies doesn't contain an await expression or statement, the method executes synchronously. Компилятор выводит предупреждения обо всех асинхронных методах, не содержащих операторы await, поскольку такая ситуация может указывать на ошибку.A compiler warning alerts you to any async methods that don't contain await statements, because that situation might indicate an error. См. раздел Предупреждение компилятора (уровень 1) CS4014.See Compiler Warning (level 1) CS4014.

Ключевое слово async — это контекстно-зависимо ключевое слово, которое является ключевым словом, когда оно изменяет метод, лямбда-выражение или анонимный метод.The async keyword is contextual in that it's a keyword only when it modifies a method, a lambda expression, or an anonymous method. Во всех других контекстах он интерпретируется как идентификатор.In all other contexts, it's interpreted as an identifier.

ПримерExample

В следующем примере показана структура и поток управления между обработчиком асинхронных событий StartButton_Click и асинхронным методом ExampleMethodAsync.The following example shows the structure and flow of control between an async event handler, StartButton_Click, and an async method, ExampleMethodAsync. В результате выполнения этого асинхронного метода возвращается число символов на веб-странице.The result from the async method is the number of characters of a web page. Код подходит для приложения Windows Presentation Foundation (WPF) или приложения для Магазина Windows Presentation Foundation (WPF), которые создаются в Visual Studio; см. комментарии к коду для настройки приложения.The code is suitable for a Windows Presentation Foundation (WPF) app or Windows Store app that you create in Visual Studio; see the code comments for setting up the app.

Этот код можно выполнить в Visual Studio как приложение Windows Presentation Foundation (WPF) или приложение Магазина Windows.You can run this code in Visual Studio as a Windows Presentation Foundation (WPF) app or a Windows Store app. Вам понадобятся элементы управления типа "Кнопка" (StartButton) и "Текстовое поле" (ResultsTextBox).You need a Button control named StartButton and a Textbox control named ResultsTextBox. Не забудьте задать имена и обработчик, чтобы получить код следующего вида:Remember to set the names and handler so that you have something like this:

<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:To run the code as a WPF app:

  • Вставьте этот код в класс MainWindow в MainWindow.xaml.cs.Paste this code into the MainWindow class in MainWindow.xaml.cs.
  • Добавьте ссылку на System.Net.Http.Add a reference to System.Net.Http.
  • Добавьте директиву using для System.Net.Http.Add a using directive for System.Net.Http.

Выполнение кода в виде приложения Магазина Windows:To run the code as a Windows Store app:

  • Вставьте этот код в класс MainPage в MainPage.xaml.cs.Paste this code into the MainPage class in MainPage.xaml.cs.
  • Добавьте директивы using для System.Net.Http и System.Threading.Tasks.Add using directives for System.Net.Http and 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.For more information about tasks and the code that executes while waiting for a task, see Asynchronous Programming with async and await. Полный пример WPF, в котором используются аналогичные элементы, см. в статье Пошаговое руководство. Получение доступа к Интернету с помощью модификатора Async и оператора Await (C#).For a full WPF example that uses similar elements, see Walkthrough: Accessing the Web by Using Async and Await.

Типы возвращаемых значенийReturn Types

Асинхронные методы могут иметь следующие типы возвращаемых значений:An async method can have the following return types:

  • Task
  • Task<TResult>
  • void.void. Методы async void обычно рекомендуются для кода, отличного от обработчиков событий, поскольку вызывающие объекты не могут await эти методы и должны реализовать другой механизм уведомления об успешном завершении или ошибках.async void methods are generally discouraged for code other than event handlers because callers cannot await those methods and must implement a different mechanism to report successful completion or error conditions.
  • Начиная с версии 7.0 в языке C# поддерживаются любые типы с доступным методом GetAwaiter.Starting with C# 7.0, any type that has an accessible GetAwaiter method. Одной из таких реализаций является тип System.Threading.Tasks.ValueTask<TResult>.The System.Threading.Tasks.ValueTask<TResult> type is one such implementation. Доступ к нему осуществляется посредством пакета NuGet System.Threading.Tasks.Extensions.It is available by adding the NuGet package System.Threading.Tasks.Extensions.

Асинхронный метод не может объявлять параметры in, ref или out, а также иметь ссылочное возвращаемое значение, но он может вызывать методы с такими параметрами.The async method can't declare any in, ref or out parameters, nor can it have a reference return value, but it can call methods that have such parameters.

Task<TResult> указывается в качестве возвращаемого типа асинхронного метода, если оператор return метода задает операнд типа TResult.You specify Task<TResult> as the return type of an async method if the return statement of the method specifies an operand of type TResult. Класс Task используется при отсутствии содержательного значения, возвращаемого методом при его завершении.You use Task if no meaningful value is returned when the method is completed. То есть вызов метода возвращает Task, однако когда Task завершен, любое выражение await, которое ожидает Task, возвращает значение void.That is, a call to the method returns a Task, but when the Task is completed, any await expression that's awaiting the Task evaluates to void.

Возвращаемый тип void используется в основном для определения обработчиков событий, которые требуют этого возвращаемого типа.You use the void return type primarily to define event handlers, which require that return type. Вызывающий объект асинхронного метода, возвращающего void, не может ожидать его и перехватывать создаваемые методом исключения.The caller of a void-returning async method can't await it and can't catch exceptions that the method throws.

Начиная с версии C# 7.0, возвращается другой тип, обычно тип значения, с методом GetAwaiter, что позволяет свести к минимуму операции выделения памяти в разделах кода с критическими требованиями к производительности.Starting with C# 7.0, you return another type, typically a value type, that has a GetAwaiter method to minimize memory allocations in performance-critical sections of code.

Дополнительные сведения и примеры см. в разделе Асинхронные типы возвращаемых значений.For more information and examples, see Async Return Types.

См. такжеSee also