🎯 Objetivo: Neste capítulo, você irá dominar a programação assíncrona em C# usando as palavras-chave async e await. Isso permitirá que seus programas realizem operações demoradas (como chamadas de rede ou acesso a banco de dados) sem travar a interface do usuário ou bloquear o processamento de outras requisições.
Imagine que seu aplicativo precisa baixar uma foto grande da internet.
A programação assíncrona é essencial para qualquer aplicação moderna que precise de responsividade, como aplicativos web, serviços de API ou interfaces de desktop.
async e awaitEm C#, as palavras-chave async e await fornecem uma maneira simples e elegante de escrever código não-bloqueante que parece síncrono. Elas não criam novas threads, mas sim permitem que uma thread seja liberada para outras tarefas enquanto espera por uma operação de I/O (entrada/saída) demorada.
async: A palavra-chave async é usada para marcar um método como assíncrono. Ela informa ao compilador C# que o método contém um ou mais pontos de suspensão indicados por await.await: A palavra-chave await é usada dentro de um método async para "pausar" a execução até que a operação assíncrona que está sendo esperada seja concluída. Durante a pausa, a thread atual é liberada e pode executar outras tarefas. Quando a operação termina, a execução do método async é retomada.Vamos simular uma operação demorada, como uma chamada a uma API externa, usando Task.Delay(), que é a maneira padrão em C# de simular uma espera assíncrona.
using System;
using System.Threading.Tasks;
public class ExemploAsyncAwait
{
// A palavra-chave async deve ser adicionada à assinatura do método
// O tipo de retorno deve ser Task ou Task<T>
public static async Task<string> ObterDadosExternosAsync()
{
Console.WriteLine($"[1] Iniciando a operação demorada...");
// await pausa a execução do método aqui.
// A thread principal é liberada e pode fazer outras coisas.
await Task.Delay(3000); // Simula uma espera de 3 segundos
Console.WriteLine($"[2] Operação demorada concluída.");
return "Dados recebidos: Sucesso!";
}
public static async Task Main(string[] args)
{
Console.WriteLine("Início do programa na thread principal.");
// Chama o método assíncrono, mas não bloqueia a execução.
// O método retorna um objeto Task<string> imediatamente.
var tarefa = ObterDadosExternosAsync();
Console.WriteLine("[3] A thread principal continua a executar outras tarefas enquanto espera...");
Console.WriteLine("Pode-se fazer outras coisas aqui...");
// A palavra-chave await pausa a execução do método Main
// até que a 'tarefa' seja concluída. O resultado é armazenado
// na variável 'dados'.
string dados = await tarefa;
Console.WriteLine("[4] Tarefa concluída. Voltando para a thread principal.");
Console.WriteLine(dados);
}
}
Saída Esperada:
Início do programa na thread principal.
[1] Iniciando a operação demorada...
[3] A thread principal continua a executar outras tarefas enquanto espera...
Pode-se fazer outras coisas aqui...
[2] Operação demorada concluída.
[4] Tarefa concluída. Voltando para a thread principal.
Dados recebidos: Sucesso!
Perceba que a linha [3] foi executada antes das linhas [2] e [4]. Isso demonstra o comportamento não-bloqueante. O programa iniciou a operação, se afastou para fazer outras coisas, e só retomou a execução da parte await quando a operação demorada terminou.
asyncTipos:
Task<T>: Use este tipo quando o método async retorna um valor. O T é o tipo do valor que será retornado (por exemplo, Task<string>).Task: Use este tipo quando o método async não retorna um valor (void). Ele simplesmente indica que o método completou sua tarefa.void: Evite usar async void, exceto em métodos de manipuladores de eventos. O retorno void não permite que o chamador await a conclusão do método, dificultando o tratamento de erros.