💻 Exemplos: Capítulo 17: Programação Assíncrona: async/await, ValueTask e CancellationToken
💻 Exemplos: Capítulo 17: Programação Assíncrona: async/await, ValueTask e CancellationToken
Especialização em Sistemas com C# • Demonstrações Práticas Compiláveis
🎯 Objetivo dos Exemplos
Apresentar o modelo assíncrono baseado em tarefas (Task-based Asynchronous Pattern - TAP) no .NET 8: execução sem bloqueio de thread com async/await, otimização de alocação de memória com ValueTask<T> para caminhos síncronos frequentes, propagação cooperativa de cancelamento via CancellationToken e orquestração paralela com Task.WhenAll.
1. Código Fonte Completo (Program.cs)
/**
* @file Program.cs
* @brief Assincronismo moderno, ValueTask e cancelamento cooperativo em .NET 8.
*/
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
Console.WriteLine("=== CAPÍTULO 17: PROGRAMAÇÃO ASSÍNCRONA E CANCELLATIONTOKEN ===");
// 1. Método com ValueTask<T> para Otimização de Caminho Síncrono (Cache Hit)
static ValueTask<string> ObterConfiguracaoAsync(string chave, bool emCache)
{
if (emCache)
{
// Retorno síncrono instantâneo: Zero alocação de objeto Task no Heap!
return ValueTask.FromResult("VALOR_CACHE_LOCAL_OK");
}
// Caminho assíncrono real (I/O)
return new ValueTask<string>(ConsultarBancoRemotoAsync(chave));
}
static async Task<string> ConsultarBancoRemotoAsync(string chave)
{
await Task.Delay(100); // Simula latência de rede assíncrona
return $"VALOR_REMOTO_PARA_{chave}";
}
// 2. Operação Longa com Suporte a CancellationToken
static async Task ProcessarFilaEventosAsync(int totalItens, CancellationToken ct)
{
Console.WriteLine($"[Worker] Iniciando processamento de {totalItens} itens...");
for (int i = 1; i <= totalItens; i++)
{
// Verifica se o chamador solicitou interrupção cooperativa
ct.ThrowIfCancellationRequested();
await Task.Delay(50, ct); // Passa o token para a operação assíncrona
Console.WriteLine($" -> Item #{i} processado com sucesso.");
}
Console.WriteLine("[Worker] Processamento concluido!");
}
// Execução 1: Teste com ValueTask
string resCache = await ObterConfiguracaoAsync("timeout", emCache: true);
Console.WriteLine($"Resultado via Cache (ValueTask Sincrona): {resCache}");
string resRemoto = await ObterConfiguracaoAsync("gateway_ip", emCache: false);
Console.WriteLine($"Resultado via I/O (ValueTask Assincrona): {resRemoto}");
// Execução 2: Teste de Cancelamento Cooperativo com Timeout
Console.WriteLine("\n--- Testando Cancelamento com CancellationTokenSource ---");
using CancellationTokenSource cts = new(TimeSpan.FromMilliseconds(120)); // Cancela após 120ms
try
{
await ProcessarFilaEventosAsync(10, cts.Token);
}
catch (OperationCanceledException)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("[CANCELAMENTO COOPERATIVO] A operacao foi interrompida com seguranca pelo CancellationToken!");
Console.ResetColor();
}
// Execução 3: Orquestração Paralela com Task.WhenAll
Console.WriteLine("\n--- Disparando Múltiplas Tarefas Paralelas via Task.WhenAll ---");
Stopwatch sw = Stopwatch.StartNew();
Task<string> task1 = ConsultarBancoRemotoAsync("TABELA_USUARIOS");
Task<string> task2 = ConsultarBancoRemotoAsync("TABELA_SENSORES");
Task<string> task3 = ConsultarBancoRemotoAsync("TABELA_AUDITORIA");
string[] resultados = await Task.WhenAll(task1, task2, task3);
sw.Stop();
Console.WriteLine($"3 consultas de 100ms executaram em paralelo em apenas {sw.ElapsedMilliseconds} ms!");
foreach (string r in resultados)
{
Console.WriteLine($" -> {r}");
}
2. Instruções de Compilação e Execução
dotnet new console -n AppAsync -f net8.0
cd AppAsync
dotnet run
3. Saída Esperada no Terminal
=== CAPÍTULO 17: PROGRAMAÇÃO ASSÍNCRONA E CANCELLATIONTOKEN ===
Resultado via Cache (ValueTask Sincrona): VALOR_CACHE_LOCAL_OK
Resultado via I/O (ValueTask Assincrona): VALOR_REMOTO_PARA_gateway_ip
--- Testando Cancelamento com CancellationTokenSource ---
[Worker] Iniciando processamento de 10 itens...
-> Item #1 processado com sucesso.
-> Item #2 processado com sucesso.
[CANCELAMENTO COOPERATIVO] A operacao foi interrompida com seguranca pelo CancellationToken!
--- Disparando Múltiplas Tarefas Paralelas via Task.WhenAll ---
3 consultas de 100ms executaram em paralelo em apenas 108 ms!
-> VALOR_REMOTO_PARA_TABELA_USUARIOS
-> VALOR_REMOTO_PARA_TABELA_SENSORES
-> VALOR_REMOTO_PARA_TABELA_AUDITORIA