Trabalhos agendados com Quartz.NET
Defina trabalhos e gatilhos com Quartz.NET, use expressões cron e integre tudo ao DI do ASP.NET Core.
Trabalhos agendados com Quartz.NET é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.
Por que Quartz.NET
Quando você precisa de expressões cron, persistência de trabalhos, agrupamento, políticas de repetição e cadeias de trabalhos — o Quartz.NET fornece um agendador pronto para produção, além do que o PeriodicTimer oferece. Ele é a versão .NET do popular agendador Quartz para Java.
Instalando o Quartz.NET
Adicione os pacotes Quartz e Quartz.AspNetCore. A integração com o ASP.NET registra automaticamente o agendador como um serviço hospedado.
# Install packages
dotnet add package Quartz
dotnet add package Quartz.AspNetCore
# Optional: persistence (requires Quartz.Serialization.Json too)
# dotnet add package Quartz.Jobs
# dotnet add package Quartz.PluginsDefinindo um trabalho
Implemente IJob (ou IAsyncJob nas versões mais recentes do Quartz) com um método Execute. O contexto do trabalho fornece dados de execução e informações sobre o gatilho atual.
using Quartz;
[DisallowConcurrentExecution] // prevent overlapping executions
public class ReportGeneratorJob : IJob
{
private readonly IReportService _reports;
private readonly ILogger<ReportGeneratorJob> _logger;
public ReportGeneratorJob(IReportService r, ILogger<ReportGeneratorJob> l)
{ _reports = r; _logger = l; }
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation("Generating report at {Time}", DateTime.UtcNow);
await _reports.GenerateDailyReportAsync(context.CancellationToken);
_logger.LogInformation("Report generated");
}
}Registrando o Quartz no ASP.NET Core
Use AddQuartz para configurar o agendador e AddQuartzHostedService para executá-lo como um IHostedService. Os trabalhos e gatilhos são configurados na expressão lambda.
builder.Services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionJobFactory();
var jobKey = new JobKey("ReportGenerator");
q.AddJob<ReportGeneratorJob>(opts => opts.WithIdentity(jobKey));
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity("ReportTrigger")
.WithCronSchedule("0 0 8 * * ?") // 8:00 AM daily
);
});
builder.Services.AddQuartzHostedService(q =>
q.WaitForJobsToComplete = true);Sintaxe de expressões cron
O Quartz usa uma expressão cron com 6 ou 7 campos: seconds minutes hours day-of-month month day-of-week [year]. A expressão cron do Quartz é ligeiramente diferente da expressão cron do Unix — os segundos vêm primeiro.
// Quartz cron format: sec min hour dom month dow [year]
"0 0 8 * * ?" // Every day at 8:00 AM
"0 0/30 9-17 * * ?" // Every 30 min, 9 AM - 5 PM weekdays
"0 0 0 1 * ?" // First day of every month at midnight
"0 0 6 ? * MON-FRI" // Every weekday at 6 AM
"0 0/5 * * * ?" // Every 5 minutes
// Tip: use cronmaker.com or crontab.guru to build expressionsGatilhos simples
Para agendas baseadas em intervalos sem a complexidade do cron, use gatilhos simples com WithSimpleSchedule.
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity("CleanupTrigger")
.StartNow()
.WithSimpleSchedule(s => s
.WithIntervalInHours(1)
.RepeatForever())
);
// Or a one-shot trigger:
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity("OneShot")
.StartAt(DateTimeOffset.UtcNow.AddMinutes(5)));Mapa de dados do trabalho
Passe parâmetros de execução aos trabalhos por meio de JobDataMap. Acesse-os dentro de Execute usando context.JobDetail.JobDataMap.
q.AddJob<EmailJob>(opts => opts
.WithIdentity("EmailJob")
.UsingJobData("to", "admin@example.com")
.UsingJobData("subject", "Daily Digest"));
// Inside the job:
public async Task Execute(IJobExecutionContext context)
{
var to = context.JobDetail.JobDataMap.GetString("to");
var subject = context.JobDetail.JobDataMap.GetString("subject");
await _mailer.SendAsync(to!, subject!, "body");
}DisallowConcurrentExecution
[DisallowConcurrentExecution] impede que uma nova instância do trabalho seja iniciada enquanto a anterior ainda estiver em execução. Isso é essencial para trabalhos que acessam recursos compartilhados.
[DisallowConcurrentExecution]
public class InventorySyncJob : IJob
{
// If a sync takes > 1 minute and triggers every minute,
// the next trigger is delayed until this one completes
public async Task Execute(IJobExecutionContext context)
{
await SyncInventoryAsync(context.CancellationToken);
}
}
// Without [DisallowConcurrentExecution], multiple instances
// could run in parallel, causing data conflicts.Tratamento de exceções e repetição
Envolva o código do trabalho em try/catch. Lance JobExecutionException para sinalizar ao Quartz que o trabalho deve ser disparado novamente imediatamente ou após um atraso.
public async Task Execute(IJobExecutionContext context)
{
try
{
await ProcessAsync(context.CancellationToken);
}
catch (TransientException ex)
{
// Ask Quartz to retry immediately
var jobException = new JobExecutionException(ex)
{
RefireImmediately = true
};
throw jobException;
}
catch (Exception ex)
{
_logger.LogError(ex, "Job failed — not retrying");
// Don't rethrow — job is done
}
}Exemplo real: agendador com vários trabalhos
Uma configuração do Quartz pronta para produção, com vários trabalhos em agendas diferentes, todos usando DI para os serviços.
builder.Services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionJobFactory();
// Daily report at 8 AM
var reportKey = new JobKey("DailyReport");
q.AddJob<ReportGeneratorJob>(o => o.WithIdentity(reportKey));
q.AddTrigger(o => o.ForJob(reportKey)
.WithCronSchedule("0 0 8 * * ?"));
// Inventory sync every 15 minutes
var syncKey = new JobKey("InventorySync");
q.AddJob<InventorySyncJob>(o => o.WithIdentity(syncKey));
q.AddTrigger(o => o.ForJob(syncKey)
.WithSimpleSchedule(s => s
.WithIntervalInMinutes(15)
.RepeatForever()));
// Cache cleanup every night at 2 AM
var cacheKey = new JobKey("CacheCleanup");
q.AddJob<CacheCleanupJob>(o => o.WithIdentity(cacheKey));
q.AddTrigger(o => o.ForJob(cacheKey)
.WithCronSchedule("0 0 2 * * ?"));
});Verificação rápida
O que o atributo [DisallowConcurrentExecution] faz em um trabalho do Quartz.NET?
Recapitulação: trabalhos agendados com Quartz.NET
Principais conclusões:
- Quartz.NET: agendador pronto para produção com cron, persistência e agrupamento
- Defina trabalhos implementando IJob com um método Execute
- Registre com AddQuartz + AddQuartzHostedService; os trabalhos são compatíveis com DI
- Formato cron: segundos minutos horas dia do mês mês dia da semana — observe que os segundos vêm primeiro
[DisallowConcurrentExecution]: aguarde a conclusão da execução atual antes de disparar novamente- Use JobDataMap para passar parâmetros de execução aos trabalhos
Aprenda C# com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 93
- Aulas
- 346
Perguntas Frequentes
A aula “Trabalhos agendados com Quartz.NET” é grátis?
Sim — o texto completo de “Trabalhos agendados com Quartz.NET” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.
O que vou aprender em “Trabalhos agendados com Quartz.NET”?
Defina trabalhos e gatilhos com Quartz.NET, use expressões cron e integre tudo ao DI do ASP.NET Core. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Trabalhos agendados com Quartz.NET”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- IHostedService e BackgroundService
- Projetos de Worker Service
- Tarefas periódicas e temporizadores
- Trabalhos agendados com Quartz.NET