💻 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