Filas e tarefas em segundo plano em C#: como acelerar sua aplicação sem dor

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que sua aplicação C# precisa de filas e tarefas em segundo plano?

\n\n

Imagine: você inicia uma aplicação web em C#, o usuário clica no botão "Enviar relatório", e… o servidor trava por 30 segundos enquanto gera o PDF. Familiar? Em 2024, os usuários não toleram lentidão. A solução — filas e tarefas em segundo plano. Elas transformam o inferno síncrono em um paraíso assíncrono.

\n\n

Neste artigo, vamos analisar como organizar corretamente o processamento em segundo plano em C#: desde o nativo Channel<T> até o industrial RabbitMQ. Você aprenderá como tirar o trabalho pesado do fluxo principal sem quebrar a arquitetura. Vamos lá!

\n\n

O que é uma fila de tarefas e por que usá-la em C#?

\n\n

Uma fila (queue) é uma estrutura de dados FIFO (First In, First Out). No contexto do C#, é um mecanismo que permite adiar a execução de uma tarefa para não bloquear o fluxo principal. Uma tarefa em segundo plano é um código executado "nos bastidores" enquanto o usuário continua navegando no site.

\n\n

Cenários típicos:

\n
    \n
  • Envio de notificações por e-mail (100 e-mails = 100 requisições ao SMTP)
  • \n
  • Geração de relatórios e arquivos Excel
  • \n
  • Processamento de imagens carregadas (redimensionamento, marca d'água)
  • \n
  • Integração com APIs externas (respostas lentas)
  • \n
  • Registro em banco de dados (para não travar a interface do usuário)
  • \n
\n\n

Sem filas, a aplicação C# vai "travar" em cada requisição pesada. Com filas, você simplesmente coloca a tarefa em um buffer e responde ao usuário: "Pronto, estamos processando".

\n\n

Opção 1: Tarefas em segundo plano com BackgroundService (nativo do .NET)

\n\n

A maneira mais simples é usar BackgroundService do Microsoft.Extensions.Hosting. Esta é a classe base para criar serviços em segundo plano no ASP.NET Core. É ideal para cenários simples onde não é necessário roteamento complexo de mensagens.

\n\n

Exemplo: processador em segundo plano com Channel<T>

\n\n

Vamos escrever um Producer-Consumer simples. O Producer (controller) coloca a tarefa no canal, o Consumer (BackgroundService) pega e executa.

\n\n
// Passo 1. Criar um canal (fila thread-safe)\npublic class TaskChannel\n{\n    private readonly Channel<string> _channel = \n        Channel.CreateBounded<string>(new BoundedChannelOptions(100)\n        {\n            FullMode = BoundedChannelFullMode.Wait\n        });\n\n    public ChannelWriter<string> Writer => _channel.Writer;\n    public ChannelReader<string> Reader => _channel.Reader;\n}\n\n// Passo 2. BackgroundService que lê do canal\npublic class EmailBackgroundService : BackgroundService\n{\n    private readonly TaskChannel _taskChannel;\n\n    public EmailBackgroundService(TaskChannel taskChannel)\n    {\n        _taskChannel = taskChannel;\n    }\n\n    protected override async Task ExecuteAsync(CancellationToken stoppingToken)\n    {\n        await foreach (var emailData in _taskChannel.Reader.ReadAllAsync(stoppingToken))\n        {\n            // Simulação de envio de e-mail (2 segundos)\n            await Task.Delay(2000, stoppingToken);\n            Console.WriteLine($"E-mail enviado: {emailData}");\n        }\n    }\n}\n\n// Passo 3. Controller que coloca as tarefas\n[ApiController]\n[Route("api/email")]\npublic class EmailController : ControllerBase\n{\n    private readonly TaskChannel _taskChannel;\n\n    public EmailController(TaskChannel taskChannel)\n    {\n        _taskChannel = taskChannel;\n    }\n\n    [HttpPost("send")]\n    public IActionResult SendEmail([FromBody] string emailData)\n    {\n        _taskChannel.Writer.TryWrite(emailData);\n        return Accepted(new { message = "E-mail colocado na fila" });\n    }\n}\n\n// Passo 4. Registro no Program.cs\nbuilder.Services.AddSingleton<TaskChannel>();\nbuilder.Services.AddHostedService<EmailBackgroundService>();
\n\n

O que está acontecendo aqui? O usuário chama POST /api/email/send — os dados vão para o ca

Blogs

Book Recommendations