Imagine uma aplicação que precisa enviar milhares de e-mails, gerar relatórios complexos ou realizar integrações com outros sistemas sem afetar a experiência do usuário. Tarefas como essas podem sobrecarregar o servidor se forem executadas no mesmo fluxo da aplicação principal. A solução? Processamento em segundo plano. Com o Hangfire, você pode lidar com essas operações de maneira confiável, agendando e monitorando cada tarefa.
Neste artigo vamos explorar passo a passo como integrar e aproveitar todo o potencial dessa ferramenta em seus projetos .NET, trazendo exemplos práticos para diferentes cenários.
O que é o Hangfire?
O Hangfire é uma biblioteca open source que permite executar tarefas em segundo plano dentro de aplicações .NET, sem a necessidade de criar serviços separados ou manipular threads manualmente. Ele é baseado em um modelo persistente que armazena as tarefas em um banco de dados, garantindo confiabilidade mesmo em caso de falhas do servidor.
Os seus principais recursos são:
- Processamento de tarefas em segundo plano: execute tarefas de forma assíncrona sem bloquear o fluxo principal da aplicação.
- Jobs recorrentes: programe tarefas para serem executadas em intervalos específicos (por exemplo, diariamente, semanalmente).
- Jobs agendados: execute tarefas em horários ou datas específicas.
- Painel de administração: um dashboard integrado que permite monitorar, reexecutar ou excluir tarefas.
Configurando o Hangfire
No terminal ou no Gerenciador de Pacotes NuGet, instale os seguintes pacotes:
Install-Package Hangfire
Install-Package Hangfire.SqlServer
dotnet add package Hangfire
dotnet add package Hangfire.SqlServer
O pacote “Hangfire” fornece a funcionalidade principal, enquanto o “Hangfire.SqlServer” permite armazenar os jobs em um banco de dados SQL Server.
Após a instalação dos pacotes, abra o arquivo “Program.cs” para configurarmos o Hangfire:
using Hangfire;
using Hangfire.SqlServer;
var builder = WebApplication.CreateBuilder(args);
// Configurar o Hangfire com SQL Server
builder.Services.AddHangfire(config =>
config.UseSqlServerStorage(builder.Configuration.GetConnectionString("DefaultConnection")));
// Adicionar o Hangfire Server
builder.Services.AddHangfireServer();
var app = builder.Build();
// Configurar o Dashboard do Hangfire
app.UseHangfireDashboard();
O “builder.Services.AddHangfire” configura o Hangfire para usar o SQL Server como mecanismo de armazenamento. A chamada “UseSqlServerStorage” especifica o banco onde os jobs serão salvos.
Em seguida o “builder.Services.AddHangfireServer” adiciona o servidor do Hangfire ao pipeline da aplicação. Esse servidor vai processar as filas de jobs.
Por fim, o “app.UseHangfireDashboard” adiciona o painel de administração para monitorar jobs. Para acessá-lo vamos usar o endpoint “/hangfire”.
Com isso, sua aplicação já está pronta para criar e executar jobs com o Hangfire.
Tipos de jobs no Hangfire
Agora vamos detalhar os tipos de jobs com exemplos de uso.
Tarefas em fila (Enqueue)
O primeiro tipo de jobs que vamos falar é o “Enqueue”, com o qual criamos uma tarefa em fila, que será executada assim que possível. Para entendermos o seu funcionamento vamos considerar um caso em que queremos enfileirar a execução de um método específico em um serviço.
[Route("api/[controller]")]
[ApiController]
public class EmailController : ControllerBase
{
[HttpPost("Enviar")]
public IActionResult EnviarEmail([FromBody] EmailRequest request)
{
BackgroundJob.Enqueue(service =>
service.EnviarEmail(request.Destinatario, request.Assunto, request.Mensagem));
return Ok("E-mail enfileirado para envio!");
}
}
No código acima, adicionamos à fila do Hangfire um job para realizar o envio de um e-mail como notificação para o usuário. O método “Enqueue<IEmailService>” é usado para informar ao Hangfire que queremos utilizar os métodos definidos na implementação da interface “IEmailService”.
Após definir o tipo do serviço (IEmailService), utilizamos uma expressão lambda “service => service.EnviarEmail(…)” para indicar qual método queremos executar — no caso, o método “EnviarEmail”. Através dessa expressão, temos acesso aos métodos disponíveis no serviço implementado e podemos passar os argumentos necessários, como o destinatário, o assunto e a mensagem do e-mail.
Perceba que quando usamos o tipo genérico no método “Enqueue<T>()” do Hangfire, não é necessário realizar a injeção de dependência manualmente no controlador ou serviço em que a tarefa está sendo enfileirada. O Hangfire é responsável por resolver a dependência do tipo genérico especificado (T) usando o contêiner de injeção de dependência configurado na aplicação.
A seguir vamos ver as tarefas agendadas e nela vamos implementar o exemplo usando a injeção de dependência.
Tarefas agendadas (Schedule)
Tarefas agendadas são úteis quando você precisa realizar um job em um momento futuro, mas com uma espera configurada. O método “BackgroundJob.Schedule” permite que você agende a execução de um job em um intervalo específico.
Imagine que você tem uma aplicação que precisa enviar um lembrete para o usuário sobre uma reunião que está prestes a ocorrer. Você pode agendar o envio da notificação para ocorrer alguns minutos antes do evento.
private readonly INotificacaoService _notificacaoService;
public ReuniaoController(INotificacaoService notificacaoService)
{
_notificacaoService = notificacaoService;
}
[HttpPost("agendar-reuniao")]
public ActionResult AgendarReuniao(DateTime dataReuniao, string usuarioEmail)
{
var intervalo = dataReuniao - DateTime.Now;
BackgroundJob.Schedule(
() => _notificacaoService.EnviarLembrete(usuarioEmail),
intervalo.Subtract(TimeSpan.FromMinutes(10))
);
return Ok();
}
O método “BackgroundJob.Schedule” agenda a execução do método “EnviarLembrete” para ocorrer daqui a 10 minutos, enviando, assim, um e-mail de lembrete para o usuário.
No exemplo de implementação do método “Schedule”, utilizamos a interface “INotificacaoService”, que foi injetada no controlador por meio do construtor. Essa abordagem é uma alternativa ao exemplo anterior, em que não foi necessária a injeção direta da dependência no controlador, pois o Hangfire resolve automaticamente as dependências ao usar o tipo genérico no método “Enqueue”.
Tarefas recorrentes (Recurring)
As tarefas recorrentes são indicadas para jobs que precisam ser executados em intervalos regulares, como enviar relatórios diários ou realizar sincronizações de dados.
Se você tem uma aplicação que precisa enviar um relatório diário de atividades para um administrador, você pode usar o Hangfire para configurar esse job para rodar automaticamente todos os dias.
public class AgendamentoDeTarefas
{
private readonly IRelatorioService _relatorioService;
public AgendamentoDeTarefas(IRelatorioService relatorioService)
{
_relatorioService = relatorioService;
}
public void AgendarRelatorioDiario()
{
RecurringJob.AddOrUpdate(
"relatorio-diario",
() => _relatorioService.EnviarRelatorioDiario(),
Cron.Daily
);
}
}
O “AddOrUpdate” possui um identificador que no exemplo acima é “relatorio-diario”. Esse identificador é útil para identificar o job recorrente e também quando for necessário atualizar ou remover esse job. Trataremos sobre isso mais à frente. Em seguida ele recebe o método que deve ser executado e, por fim, a frequência com que o job será executado.
O Hangfire oferece suporte à sintaxe de “cron” para configurar facilmente horários recorrentes.
- Cron.Daily: executa o job uma vez ao dia, geralmente à meia-noite.
- Cron.Minutely: executa a cada minuto.
- Cron.Hourly: executa a cada hora.
- Cron.Weekly: executa uma vez por semana.
- Cron.Monthly: executa uma vez por mês.
Caso precise configurar horários específicos, você pode usar expressões cron personalizadas:
“0 9 * * *” | Executa todos os dias às 9:00. |
“0 */15 * * *” | Executa a cada 15 minutos. |
“0 0 * * 0” | Executa todo domingo à meia-noite. |
“0 0 1 * *” | Executa no primeiro dia de cada mês. |
Exemplo:
RecurringJob.AddOrUpdate(
"relatorio-diario",
() => _relatorioService.EnviarRelatorioDiario(),
"0 9 * * *"
);
Tarefas dependentes (ContinueWith)
O método “ContinueWith” permite que você encadeie tarefas, com a execução de uma tarefa dependendo da conclusão de outra. Isso é útil para cenários em que um processo precisa ser feito em sequência, como primeiro processar dados e depois gerar um relatório.
Imaginemos que em uma aplicação de e-commerce você precisa processar um pedido de um cliente e, após a conclusão desse processo, enviar um e-mail de confirmação.
public class PedidoController : ControllerBase
{
private readonly IPedidoService _pedidoService;
private readonly INotificacaoService _notificacaoService;
public PedidoController(IPedidoService pedidoService, INotificacaoService notificacaoService)
{
_pedidoService = pedidoService;
_notificacaoService = notificacaoService;
}
[HttpPost("finalizar-pedido")]
public ActionResult FinalizarPedido(int pedidoId)
{
var jobId = BackgroundJob.Enqueue(() =>
_pedidoService.ProcessarPedido(pedidoId));
BackgroundJob.ContinueWith(jobId, () =>
_notificacaoService.EnviarConfirmacao(pedidoId));
return Ok();
}
}
Primeiro, o pedido é processado usando “BackgroundJob.Enqueue”, e seu “jobId” é armazenado. Depois, com o método “BackgroundJob.ContinueWith”, a tarefa de enviar a notificação de confirmação é agendada para ser executada apenas após a conclusão do processamento do pedido.
Monitorando e gerenciando jobs com o painel do Hangfire
Agora que vimos como configurar e executar diversos tipos de jobs no Hangfire, é essencial entender como monitorar e gerenciar a execução dessas tarefas. Para isso, o Hangfire fornece um painel de administração robusto e intuitivo, no qual podemos visualizar o status dos jobs, analisar falhas, acompanhar agendamentos e até mesmo interagir diretamente com os jobs configurados.
Acessando o painel do Hangfire
O painel de administração do Hangfire é uma ferramenta bastante útil para monitorar e gerenciar tarefas em segundo plano. Ele fornece uma interface intuitiva para acompanhar o status dos jobs, corrigir problemas e ajustar cronogramas, tornando o Hangfire uma solução bastante indicada para gerenciamento de jobs em aplicações .NET.
Acelere a sua carreira conosco!
Se você é Desenvolvedor .NET Júnior e quer acelerar sua carreira até nível Pleno com salário de R$7k+, ou mesmo busca a primeira vaga, conheça a Mentoria .NET Start: Clique aqui
Se é Desenvolvedor .NET Pleno ou Sênior e quer virar referência técnica em sua equipe e mercado, com salário de R$10k+, conheça a Mentoria .NET Expert: Clique aqui
Conclusão
O Hangfire simplifica a execução de tarefas em segundo plano em aplicações .NET, oferecendo um modelo robusto e escalável. Seus recursos de monitoramento e agendamento o tornam uma ferramenta indispensável para desenvolvedores. Com as práticas e exemplos apresentados, você está pronto para integrá-lo com segurança em seus projetos. Explore mais sobre o Hangfire na documentação oficial.