Compartilhar via


async (Referência de C#)

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

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

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

string contents = await httpClient.GetStringAsync(requestUrl);

Um método assíncrono será executado de forma síncrona até atingir sua primeira expressão await e, nesse ponto, ele será suspenso até que a tarefa aguardada seja concluída. Enquanto isso, o controle será retornado ao chamador do método, como exibido no exemplo da próxima seção.

Se o método que a palavra-chave async modifica não contiver uma expressão ou instrução await, ele será executado de forma síncrona. Um aviso do compilador o alertará sobre quaisquer métodos assíncronos que não contenham instruções await, pois essa situação poderá indicar um erro. Consulte Aviso do compilador (nível 1) CS4014.

A palavra-chave async é contextual, pois ela será uma palavra-chave somente quando modificar um método, uma expressão lambda ou um método anônimo. Em todos os outros contextos, ela será interpretada como um identificador.

Exemplo

O exemplo a seguir mostra a estrutura e o fluxo de controle entre um manipulador de eventos assíncronos, StartButton_Click 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 será adequado para um aplicativo do WPF (Windows Presentation Foundation) ou da Windows Store que você criar no Visual Studio, consulte os comentários do código para configurar o aplicativo.

Você pode executar esse código no Visual Studio como um aplicativo do WPF (Windows Presentation Foundation) ou um aplicativo da Windows Store. Você precisa de um controle de botão chamado StartButton e de um controle de caixa de texto 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 este código na classe MainWindow em MainWindow.xaml.cs.
  • Adicione uma referência a System.Net.Http.
  • Adicione uma diretiva using a System.Net.Http.

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

  • Cole este código na classe MainPage em MainPage.xaml.cs.
  • Adicione diretivas using 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 async e await. Para obter um exemplo de console completo que usa elementos semelhantes, consulte Processar tarefas assíncronas à medida que elas são concluídas (C#).

Tipos de retorno

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

  • Task
  • Task<TResult>
  • void. Os métodos async void geralmente são desencorajados para código que não são manipuladores de eventos, porque os chamadores não podem await esses métodos e devem implementar um mecanismo diferente para relatar a conclusão bem-sucedida ou condições de erro.
  • Qualquer tipo que tenha um método GetAwaiter acessível. O tipo System.Threading.Tasks.ValueTask<TResult> é um exemplo de uma implementação assim. Ele está disponível ao adicionar o pacote NuGet System.Threading.Tasks.Extensions.

O método assíncrono não pode declarar os parâmetros in, ref nem out e também não pode ter um valor retornado por referência, mas pode chamar métodos que tenham esses parâmetros.

Você especificará Task<TResult> como o tipo de retorno de um método assíncrono se a instrução return do método especificar um operando do tipo TResult. Você usará Task se nenhum valor significativo for retornado quando o método for concluído. Isto é, uma chamada ao método retorna uma Task, mas quando a Task for concluída, qualquer expressão await que esteja aguardando a Task será avaliada como void.

O tipo de retorno void é usado principalmente para definir manipuladores de eventos que exigem esse tipo de retorno. O chamador de um método assíncrono de retorno void não pode aguardá-lo e capturar exceções acionadas pelo método.

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

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

Confira também