Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
38m 57s
A programação assíncrona pode parecer intimidante devido à sua terminologia complexa, mas oferece benefícios significativos, tornando os aplicativos mais rápidos e responsivos. O vídeo de Tim Corey sobre " C# Async/Await - Torne seu aplicativo mais responsivo e rápido com programação assíncrona " fornece um guia prático sobre como usar esses recursos de forma eficaz.
Neste artigo, usaremos o vídeo detalhado de Tim Corey para explicar esses conceitos, demonstrando as aplicações práticas de async e await por meio de exemplos claros. Abordaremos diversos cenários, desde manipuladores de eventos assíncronos até o gerenciamento de múltiplas tarefas, contextos de sincronização, tratamento de erros e as armadilhas comuns, como o uso de métodos assíncronos com a propriedade void. Ao final deste artigo, você terá um sólido entendimento de programação assíncrona e de como implementá-la em suas próprias aplicações C#.
A programação assíncrona em C# é essencial para melhorar o desempenho das aplicações, especialmente ao trabalhar com operações que dependem muito de E/S ou de CPU. As palavras-chave async e await permitem que os desenvolvedores escrevam código assíncrono que pode executar tarefas de longa duração sem bloquear o thread principal. Ao marcar um método com a palavra-chave async, você sinaliza que o método realizará uma operação assíncrona, retornando um Task ou Task<t>. A palavra-chave await é usada dentro de um método assíncrono para pausar a execução até que a tarefa aguardada seja concluída, permitindo que outras operações sejam executadas simultaneamente.
Ao contrário da programação síncrona, em que as tarefas são executadas sequencialmente e podem bloquear a thread de chamada, os métodos assíncronos permitem lidar com várias tarefas simultaneamente, como processos em segundo plano ou processamento de entrada do usuário, sem congelar a thread da interface do usuário. Neste artigo, exploraremos como async e await funcionam juntos, cobrindo conceitos como métodos async void, tratamento de erros, trocas de contexto e contextos de sincronização. Você aprenderá como gerenciar com eficiência múltiplas operações assíncronas e lidar com exceções, garantindo uma execução tranquila em toda a thread de chamada, thread da interface do usuário e conclusão da tarefa. Essa abordagem é particularmente útil em cenários que envolvem sistemas de arquivos, solicitações de rede ou solicitações simultâneas, onde a capacidade de resposta é fundamental.
Tim introduz a programação assíncrona explicando a diferença entre operações síncronas e assíncronas. Na programação síncrona, as tarefas são executadas sequencialmente, causando atrasos se uma tarefa demorar muito. A programação assíncrona permite que as tarefas sejam executadas em paralelo ou em segundo plano, melhorando o desempenho e a capacidade de resposta.
Tim destaca dois benefícios principais da programação assíncrona:
Melhoria na capacidade de resposta da interface do usuário (IU) : Ao executar tarefas de forma assíncrona, a IU permanece responsiva mesmo durante a execução de operações demoradas.
Execução paralela : Tarefas independentes podem ser executadas em paralelo, reduzindo o tempo total necessário para concluí-las.
Tim configura um aplicativo de demonstração do Windows Presentation Foundation (WPF) para demonstrar a diferença entre operações síncronas e assíncronas. O aplicativo possui dois botões: um para executar tarefas de forma síncrona e outro para executá-las de forma assíncrona.

O aplicativo também inclui um painel de resultados para exibir a saída.
Tim explica o código por trás da operação síncrona. Um Stopwatch é usado para medir o tempo de execução da tarefa.
private void ExecuteSync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
List<string> websites = GetWebsiteList();
foreach (var website in websites)
{
string result = DownloadWebsite(website);
ReportWebsiteInfo(website, result);
}
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}
private List<string> GetWebsiteList()
{
return new List<string>
{
"https://www.yahoo.com",
"https://www.google.com",
"https://www.microsoft.com",
"https://www.cnn.com",
"https://www.codeproject.com",
"https://www.stackoverflow.com"
};
}
private string DownloadWebsite(string websiteURL)
{
WebClient client = new WebClient();
return client.DownloadString(websiteURL);
}
private void ReportWebsiteInfo(string website, string data)
{
ResultsWindow.Text += $"{website}: {data.Length} characters{Environment.NewLine}";
}Private Sub ExecuteSync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Dim websites As List(Of String) = GetWebsiteList()
For Each website In websites
Dim result As String = DownloadWebsite(website)
ReportWebsiteInfo(website, result)
Next
stopwatch.Stop()
ResultsWindow.Text &= $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End Sub
Private Function GetWebsiteList() As List(Of String)
Return New List(Of String) From {
"https://www.yahoo.com",
"https://www.google.com",
"https://www.microsoft.com",
"https://www.cnn.com",
"https://www.codeproject.com",
"https://www.stackoverflow.com"
}
End Function
Private Function DownloadWebsite(websiteURL As String) As String
Dim client As New WebClient()
Return client.DownloadString(websiteURL)
End Function
Private Sub ReportWebsiteInfo(website As String, data As String)
ResultsWindow.Text &= $"{website}: {data.Length} characters{Environment.NewLine}"
End SubPrivate Sub ExecuteSync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Dim websites As List(Of String) = GetWebsiteList()
For Each website In websites
Dim result As String = DownloadWebsite(website)
ReportWebsiteInfo(website, result)
Next
stopwatch.Stop()
ResultsWindow.Text &= $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End Sub
Private Function GetWebsiteList() As List(Of String)
Return New List(Of String) From {
"https://www.yahoo.com",
"https://www.google.com",
"https://www.microsoft.com",
"https://www.cnn.com",
"https://www.codeproject.com",
"https://www.stackoverflow.com"
}
End Function
Private Function DownloadWebsite(websiteURL As String) As String
Dim client As New WebClient()
Return client.DownloadString(websiteURL)
End Function
Private Sub ReportWebsiteInfo(website As String, data As String)
ResultsWindow.Text &= $"{website}: {data.Length} characters{Environment.NewLine}"
End SubEste código executa os seguintes passos:
Tim executa o aplicativo para demonstrar a operação síncrona. Ele observa que a interface do usuário deixa de responder enquanto os sites estão sendo baixados e que os resultados são exibidos todos de uma vez após a conclusão dos downloads.

Para uma demonstração prática da forma imóvel, assista ao vídeo para melhor compreensão a partir de 9:20.
Tim resolve o primeiro problema convertendo o método síncrono em um método assíncrono. Isso envolve o uso das palavras-chave async e await. Segue uma explicação passo a passo do processo:
Copiar método síncrono existente : Tim copia o método síncrono existente e renomeia-o para indicar que ele será assíncrono.
private async Task RunDownloadAsync()
{
// Same code as RunDownloadSync, but will be modified for async
}private async Task RunDownloadAsync()
{
// Same code as RunDownloadSync, but will be modified for async
}Private Async Function RunDownloadAsync() As Task
' Same code as RunDownloadSync, but will be modified for async
End FunctionPrivate Async Function RunDownloadAsync() As Task
' Same code as RunDownloadSync, but will be modified for async
End FunctionModificar a chamada de download para execução assíncrona :
Task.Run para executá-la assíncronamente.private async Task<WebsiteDataModel> DownloadWebsiteAsync(string websiteURL)
{
return await Task.Run(() => DownloadWebsite(websiteURL));
}private async Task<WebsiteDataModel> DownloadWebsiteAsync(string websiteURL)
{
return await Task.Run(() => DownloadWebsite(websiteURL));
}Private Async Function DownloadWebsiteAsync(websiteURL As String) As Task(Of WebsiteDataModel)
Return Await Task.Run(Function() DownloadWebsite(websiteURL))
End FunctionPrivate Async Function DownloadWebsiteAsync(websiteURL As String) As Task(Of WebsiteDataModel)
Return Await Task.Run(Function() DownloadWebsite(websiteURL))
End Functionawait garante que o método espere que a tarefa assíncrona seja concluída antes de continuar.Certifique-se de que o método seja assíncrono :
async, e ela retorna um Task.private async Task RunDownloadAsync()
{
List<string> websites = GetWebsiteList();
foreach (var website in websites)
{
var result = await DownloadWebsiteAsync(website);
ReportWebsiteInfo(website, result);
}
}private async Task RunDownloadAsync()
{
List<string> websites = GetWebsiteList();
foreach (var website in websites)
{
var result = await DownloadWebsiteAsync(website);
ReportWebsiteInfo(website, result);
}
}Private Async Function RunDownloadAsync() As Task
Dim websites As List(Of String) = GetWebsiteList()
For Each website In websites
Dim result = Await DownloadWebsiteAsync(website)
ReportWebsiteInfo(website, result)
Next
End FunctionPrivate Async Function RunDownloadAsync() As Task
Dim websites As List(Of String) = GetWebsiteList()
For Each website In websites
Dim result = Await DownloadWebsiteAsync(website)
ReportWebsiteInfo(website, result)
Next
End FunctionLide com o evento corretamente :
private async void ExecuteAsync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
await RunDownloadAsync();
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}private async void ExecuteAsync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
await RunDownloadAsync();
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}Private Async Sub ExecuteAsync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Await RunDownloadAsync()
stopwatch.Stop()
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End SubPrivate Async Sub ExecuteAsync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Await RunDownloadAsync()
stopwatch.Stop()
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End SubObserve que os manipuladores de eventos podem retornar void mesmo que chamem métodos assíncronos.
Tim mostra que, ao usar a palavra-chave await, a interface do usuário permanece responsiva. Isso permite que os usuários interajam com a janela enquanto a tarefa assíncrona está em execução.
// UI remains responsive
private async void ExecuteAsync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
await RunDownloadAsync();
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}// UI remains responsive
private async void ExecuteAsync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
await RunDownloadAsync();
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}' UI remains responsive
Private Async Sub ExecuteAsync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Await RunDownloadAsync()
stopwatch.Stop()
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End Sub' UI remains responsive
Private Async Sub ExecuteAsync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Await RunDownloadAsync()
stopwatch.Stop()
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End SubPara garantir que o tempo total de execução seja relatado corretamente, Tim adiciona a palavra-chave await à chamada no manipulador de eventos de clique do botão.
// Correctly waits for the asynchronous task to complete
private async void ExecuteAsync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
await RunDownloadAsync();
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}// Correctly waits for the asynchronous task to complete
private async void ExecuteAsync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
await RunDownloadAsync();
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}' Correctly waits for the asynchronous task to complete
Private Async Sub ExecuteAsync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Await RunDownloadAsync()
stopwatch.Stop()
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End Sub' Correctly waits for the asynchronous task to complete
Private Async Sub ExecuteAsync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Await RunDownloadAsync()
stopwatch.Stop()
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End SubAo aguardar a conclusão do método assíncrono, o tempo de execução é medido com precisão e os resultados são exibidos à medida que são obtidos.
Tim aborda a limitação de esperar que cada tarefa seja concluída sequencialmente, utilizando a execução paralela. Eis como ele modifica o código para conseguir isso:
Copie o método assíncrono existente : Tim duplica o método assíncrono existente e o renomeia para indicar execução paralela.
private async Task RunDownloadParallelAsync()
{
// Parallel execution logic will be added here
}private async Task RunDownloadParallelAsync()
{
// Parallel execution logic will be added here
}Private Async Function RunDownloadParallelAsync() As Task
' Parallel execution logic will be added here
End FunctionPrivate Async Function RunDownloadParallelAsync() As Task
' Parallel execution logic will be added here
End FunctionCriar uma lista de tarefas :
List<Task<WebsiteDataModel>> tasks = new List<Task<WebsiteDataModel>>();List<Task<WebsiteDataModel>> tasks = new List<Task<WebsiteDataModel>>();Dim tasks As New List(Of Task(Of WebsiteDataModel))()Dim tasks As New List(Of Task(Of WebsiteDataModel))()Iniciar todas as tarefas sem esperar : Em vez de aguardar cada tarefa de download imediatamente, Tim as adiciona à lista de tarefas.
foreach (var website in websites)
{
tasks.Add(DownloadWebsiteAsync(website));
}foreach (var website in websites)
{
tasks.Add(DownloadWebsiteAsync(website));
}For Each website In websites
tasks.Add(DownloadWebsiteAsync(website))
NextFor Each website In websites
tasks.Add(DownloadWebsiteAsync(website))
NextAguarde a conclusão de todas as tarefas :
Task.WhenAll é usado para aguardar a conclusão de todas as tarefas. Este método retorna uma matriz de resultados assim que todas as tarefas forem concluídas.WebsiteDataModel[] results = await Task.WhenAll(tasks);WebsiteDataModel[] results = await Task.WhenAll(tasks);Dim results As WebsiteDataModel() = Await Task.WhenAll(tasks)Dim results As WebsiteDataModel() = Await Task.WhenAll(tasks)Processar os resultados : Após a conclusão de todas as tarefas, Tim processa os resultados em um loop.
foreach (var result in results)
{
ReportWebsiteInfo(result);
}foreach (var result in results)
{
ReportWebsiteInfo(result);
}For Each result In results
ReportWebsiteInfo(result)
NextFor Each result In results
ReportWebsiteInfo(result)
NextSegue o código completo para o método de execução paralela:
private async Task RunDownloadParallelAsync()
{
List<string> websites = GetWebsiteList();
List<Task<WebsiteDataModel>> tasks = new List<Task<WebsiteDataModel>>();
foreach (var website in websites)
{
tasks.Add(DownloadWebsiteAsync(website));
}
WebsiteDataModel[] results = await Task.WhenAll(tasks);
foreach (var result in results)
{
ReportWebsiteInfo(result);
}
}private async Task RunDownloadParallelAsync()
{
List<string> websites = GetWebsiteList();
List<Task<WebsiteDataModel>> tasks = new List<Task<WebsiteDataModel>>();
foreach (var website in websites)
{
tasks.Add(DownloadWebsiteAsync(website));
}
WebsiteDataModel[] results = await Task.WhenAll(tasks);
foreach (var result in results)
{
ReportWebsiteInfo(result);
}
}Private Async Function RunDownloadParallelAsync() As Task
Dim websites As List(Of String) = GetWebsiteList()
Dim tasks As New List(Of Task(Of WebsiteDataModel))()
For Each website As String In websites
tasks.Add(DownloadWebsiteAsync(website))
Next
Dim results As WebsiteDataModel() = Await Task.WhenAll(tasks)
For Each result As WebsiteDataModel In results
ReportWebsiteInfo(result)
Next
End FunctionPrivate Async Function RunDownloadParallelAsync() As Task
Dim websites As List(Of String) = GetWebsiteList()
Dim tasks As New List(Of Task(Of WebsiteDataModel))()
For Each website As String In websites
tasks.Add(DownloadWebsiteAsync(website))
Next
Dim results As WebsiteDataModel() = Await Task.WhenAll(tasks)
For Each result As WebsiteDataModel In results
ReportWebsiteInfo(result)
Next
End FunctionTim atualiza o manipulador de eventos de clique do botão para chamar o novo método de execução paralela.
private async void ExecuteAsync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
await RunDownloadParallelAsync();
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}private async void ExecuteAsync_Click(object sender, RoutedEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
await RunDownloadParallelAsync();
stopwatch.Stop();
ResultsWindow.Text += $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}";
}Private Async Sub ExecuteAsync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Await RunDownloadParallelAsync()
stopwatch.Stop()
ResultsWindow.Text &= $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End SubPrivate Async Sub ExecuteAsync_Click(sender As Object, e As RoutedEventArgs)
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
Await RunDownloadParallelAsync()
stopwatch.Stop()
ResultsWindow.Text &= $"Total execution time: {stopwatch.ElapsedMilliseconds} ms{Environment.NewLine}"
End SubAo esperar por RunDownloadParallelAsync, o tempo total de execução é medido e relatado com precisão.
Tim demonstra a melhoria de desempenho executando o aplicativo em paralelo. Os resultados mostram uma redução significativa no tempo total de execução em comparação com a execução sequencial.
// Parallel execution
async Task RunDownloadParallelAsync();// Parallel execution
async Task RunDownloadParallelAsync();' Parallel execution
Async Function RunDownloadParallelAsync() As Task
End Function' Parallel execution
Async Function RunDownloadParallelAsync() As Task
End FunctionO aumento de velocidade é evidente, pois os sites são baixados simultaneamente, reduzindo o tempo total de espera à duração do download individual mais lento.
Task.Run() vs Chamada de Método AssíncronoTim explica o conceito de usar Task.Run() para envolver um método síncrono e torná-lo assíncrono quando você não pode modificar o método original. No entanto, ele também mostra a abordagem preferida de modificar o próprio método para ser assíncrono, caso você tenha controle sobre ele.
Envolvendo Método em Task.Run():
Essa abordagem é útil quando você não pode alterar o código do método original, mas ainda deseja executá-lo de forma assíncrona.
private async Task<WebsiteDataModel> DownloadWebsiteAsync(string websiteURL)
{
return await Task.Run(() => DownloadWebsite(websiteURL));
}private async Task<WebsiteDataModel> DownloadWebsiteAsync(string websiteURL)
{
return await Task.Run(() => DownloadWebsite(websiteURL));
}Private Async Function DownloadWebsiteAsync(websiteURL As String) As Task(Of WebsiteDataModel)
Return Await Task.Run(Function() DownloadWebsite(websiteURL))
End FunctionPrivate Async Function DownloadWebsiteAsync(websiteURL As String) As Task(Of WebsiteDataModel)
Return Await Task.Run(Function() DownloadWebsite(websiteURL))
End FunctionTornando um método assíncrono :
Se for possível modificar o método, é melhor convertê-lo para assíncrono usando uma API assíncrona apropriada.
Tim demonstra isso alterando DownloadWebsite para DownloadWebsiteAsync e usando DownloadStringTaskAsync de WebClient.
private async Task<WebsiteDataModel> DownloadWebsiteAsync(string websiteURL)
{
WebClient client = new WebClient();
string data = await client.DownloadStringTaskAsync(websiteURL);
return new WebsiteDataModel { URL = websiteURL, Data = data };
}private async Task<WebsiteDataModel> DownloadWebsiteAsync(string websiteURL)
{
WebClient client = new WebClient();
string data = await client.DownloadStringTaskAsync(websiteURL);
return new WebsiteDataModel { URL = websiteURL, Data = data };
}Private Async Function DownloadWebsiteAsync(websiteURL As String) As Task(Of WebsiteDataModel)
Dim client As New WebClient()
Dim data As String = Await client.DownloadStringTaskAsync(websiteURL)
Return New WebsiteDataModel With {.URL = websiteURL, .Data = data}
End FunctionPrivate Async Function DownloadWebsiteAsync(websiteURL As String) As Task(Of WebsiteDataModel)
Dim client As New WebClient()
Dim data As String = Await client.DownloadStringTaskAsync(websiteURL)
Return New WebsiteDataModel With {.URL = websiteURL, .Data = data}
End FunctionAjustando o método de chamada :
Task.Run() e chamar diretamente o método assíncrono.private async Task RunDownloadParallelAsync()
{
List<string> websites = GetWebsiteList();
List<Task<WebsiteDataModel>> tasks = new List<Task<WebsiteDataModel>>();
foreach (var website in websites)
{
tasks.Add(DownloadWebsiteAsync(website));
}
WebsiteDataModel[] results = await Task.WhenAll(tasks);
foreach (var result in results)
{
ReportWebsiteInfo(result);
}
}private async Task RunDownloadParallelAsync()
{
List<string> websites = GetWebsiteList();
List<Task<WebsiteDataModel>> tasks = new List<Task<WebsiteDataModel>>();
foreach (var website in websites)
{
tasks.Add(DownloadWebsiteAsync(website));
}
WebsiteDataModel[] results = await Task.WhenAll(tasks);
foreach (var result in results)
{
ReportWebsiteInfo(result);
}
}Private Async Function RunDownloadParallelAsync() As Task
Dim websites As List(Of String) = GetWebsiteList()
Dim tasks As New List(Of Task(Of WebsiteDataModel))()
For Each website As String In websites
tasks.Add(DownloadWebsiteAsync(website))
Next
Dim results As WebsiteDataModel() = Await Task.WhenAll(tasks)
For Each result As WebsiteDataModel In results
ReportWebsiteInfo(result)
Next
End FunctionPrivate Async Function RunDownloadParallelAsync() As Task
Dim websites As List(Of String) = GetWebsiteList()
Dim tasks As New List(Of Task(Of WebsiteDataModel))()
For Each website As String In websites
tasks.Add(DownloadWebsiteAsync(website))
Next
Dim results As WebsiteDataModel() = Await Task.WhenAll(tasks)
For Each result As WebsiteDataModel In results
ReportWebsiteInfo(result)
Next
End FunctionTim conclui com vários pontos importantes sobre o uso de async e await:
Garantir Métodos Retornando Tasks: Sempre que você marcar um método como async, ele deve retornar um Task ou Task<t> em vez de void (exceto para manipuladores de eventos).
Use await para Operações Confiáveis: Use a palavra-chave await quando você precisar do resultado de uma operação assíncrona antes de prosseguir.
Envolvimento de Tarefa para Código Não Modificável: Use Task.Run() para envolver métodos síncronos quando não puder modificar o método original.
Marcar Métodos Assíncronos Apropriadamente: Sempre adicione Async ao nome do método para indicar que é uma operação assíncrona.
Execução paralela versus sequencial : Decida se as tarefas podem ser executadas em paralelo ou se devem esperar umas pelas outras, com base nas dependências entre elas.
Tim enfatiza que a programação assíncrona em C# foi simplificada com async, await e Task. Complexidades como contextos de threading e modelos de apartamento são gerenciadas nos bastidores.
O tutorial de Tim Corey sobre async e await em C# oferece um recurso inestimável para dominar a programação assíncrona. Ao explicar cuidadosamente conceitos como paralelismo de tarefas, responsividade da interface do usuário e a importância de usar async e await no contexto correto, Tim fornece aos desenvolvedores as ferramentas para criar aplicativos mais rápidos e responsivos. Seu passo a passo detalhado demonstra como lidar de forma eficiente com tarefas de longa duração sem bloquear a thread principal, além de estratégias para gerenciar operações assíncronas e execução paralela.
Para uma compreensão mais aprofundada e exemplos práticos adicionais, recomendo vivamente que veja o vídeo de Tim Corey. Suas ideias sobre métodos assíncronos e vazios, tratamento de erros e gerenciamento de contextos de sincronização aprimorarão ainda mais sua capacidade de implementar esses conceitos em seus projetos.
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy