assíncrono (Referência C#)

Use o async modificador para especificar que um método, expressão lambda ou método anônimo é assíncrono. Se você usar esse modificador em um método ou expressão, ele será chamado de método assíncrono. O exemplo a seguir define um método assíncrono chamado ExampleMethodAsync:

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

Se você é novo na programação assíncrona ou não entende como um método assíncrono usa o await operador para fazer um trabalho potencialmente de longa duração sem bloquear o thread do chamador, leia a introdução em Programação assíncrona com assíncrono e aguarde. O código a seguir é encontrado dentro de um método assíncrono e chama o HttpClient.GetStringAsync método:

string contents = await httpClient.GetStringAsync(requestUrl);

Um método assíncrono é executado de forma síncrona até atingir sua primeira await expressão, momento em que o método é suspenso até que a tarefa esperada seja concluída. Enquanto isso, o controle retorna ao chamador do método, como mostra o exemplo na próxima seção.

Se o método que a async palavra-chave modifica não contém uma await expressão ou instrução, o método é executado de forma síncrona. Um aviso do compilador alerta você para quaisquer métodos assíncronos que não contenham await instruções, porque essa situação pode indicar um erro. Consulte Aviso do compilador (nível 1) CS4014.

A async palavra-chave é contextual na medida em que é uma palavra-chave somente quando modifica um método, uma expressão lambda ou um método anônimo. Em todos os outros contextos, é interpretado como um identificador.

Exemplo

O exemplo a seguir mostra a estrutura e o fluxo de controle entre um manipulador StartButton_Clickde eventos assíncrono e um método assíncrono, ExampleMethodAsync. O resultado do método assíncrono é o número de caracteres de uma página da Web. O código é adequado para um aplicativo do Windows Presentation Foundation (WPF) ou aplicativo da Windows Store que você cria no Visual Studio; Consulte os comentários de código para configurar o aplicativo.

Você pode executar esse código no Visual Studio como um aplicativo do Windows Presentation Foundation (WPF) ou um aplicativo da Windows Store. Você precisa de um controle Button chamado StartButton e um controle Textbox chamado ResultsTextBox. Lembre-se de definir os nomes e o manipulador para que você tenha algo assim:

<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"/>

Para executar o código como um aplicativo WPF:

  • Cole MainWindow esse código na classe em MainWindow.xaml.cs.
  • Adicione uma referência a System.Net.Http.
  • Adicione uma using diretiva para System.Net.Http.

Para executar o código como um aplicativo da Windows Store:

  • Cole esse código na MainPage classe no MainPage.xaml.cs.
  • Adicione using diretivas para System.Net.Http e 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

Importante

Para obter mais informações sobre tarefas e o código que é executado enquanto aguarda uma tarefa, consulte Programação assíncrona com assíncrono e aguarda. Para obter um exemplo de console completo que usa elementos semelhantes, consulte Processar tarefas assíncronas à medida que são concluídas (C#).

Tipos de devolução

Um método assíncrono pode ter os seguintes tipos de retorno:

  • Task
  • Task<TResult>
  • nulo. async void Os métodos geralmente são desencorajados para códigos diferentes de manipuladores de eventos porque os chamadores não podem await esses métodos e devem implementar um mecanismo diferente para relatar condições de erro ou conclusão bem-sucedidas.
  • Qualquer tipo que tenha um método acessível GetAwaiter . O System.Threading.Tasks.ValueTask<TResult> tipo é uma dessas implementações. Ele está disponível adicionando o pacote System.Threading.Tasks.ExtensionsNuGet.

O método async não pode declarar nenhum parâmetro in, ref ou out, nem pode ter um valor de retorno de referência, mas pode chamar métodos que tenham esses parâmetros.

Você especifica Task<TResult> como o tipo de retorno de um método assíncrono se a instrução return do método especifica um operando do tipo TResult. Você usa Task se nenhum valor significativo for retornado quando o método for concluído. Ou seja, uma chamada para o método retorna um Task, mas quando o Task é concluído, qualquer await expressão que está aguardando a Task avaliação para void.

Você usa o void tipo de retorno principalmente para definir manipuladores de eventos, que exigem esse tipo de retorno. O chamador de um voidmétodo assíncrono -return não pode esperar e não pode capturar exceções que o método lança.

Você retorna outro tipo, normalmente um tipo de valor, que tem um GetAwaiter método para minimizar alocações de memória em seções críticas de desempenho do código.

Para obter mais informações e exemplos, consulte Tipos de retorno assíncronos.

Consulte também