Processi pianificati con Quartz.NET
Definisca job e trigger con Quartz.NET, usi espressioni cron e integri il tutto con la DI di ASP.NET Core.
Processi pianificati con Quartz.NET è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
Perché Quartz.NET?
Quando sono necessarie espressioni cron, persistenza dei job, clustering, criteri di retry e catene di job, Quartz.NET offre uno scheduler adatto alla produzione, con funzionalità superiori a quelle di PeriodicTimer. È il porting .NET del noto scheduler Java Quartz.
Installazione di Quartz.NET
Aggiunga i pacchetti Quartz e Quartz.AspNetCore. L'integrazione con ASP.NET registra automaticamente lo scheduler come servizio ospitato.
# 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.PluginsDefinizione di un job
Implementi IJob (oppure IAsyncJob nelle versioni più recenti di Quartz) con un metodo Execute. Il contesto del job fornisce i dati di runtime e le informazioni sul trigger corrente.
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");
}
}Registrazione di Quartz in ASP.NET Core
Utilizzi AddQuartz per configurare lo scheduler e AddQuartzHostedService per eseguirlo come IHostedService. I job e i trigger vengono configurati nella 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);Sintassi delle espressioni cron
Quartz utilizza un'espressione cron composta da 6 o 7 campi: secondi minuti ore giorno-del-mese mese giorno-della-settimana [anno]. Il cron di Quartz è leggermente diverso da quello Unix: i secondi vengono per primi.
// 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 expressionsTrigger semplici
Per le pianificazioni basate su intervalli che non richiedono la complessità di cron, utilizzi trigger semplici con 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)));Job Data Map
Passi i parametri di runtime ai job tramite JobDataMap. Vi acceda all'interno di Execute tramite 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] impedisce l'avvio di una nuova istanza del job mentre quella precedente è ancora in esecuzione. È essenziale per i job che accedono a risorse condivise.
[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.Gestione delle eccezioni e retry
Racchiuda il codice del job in try/catch. Generi JobExecutionException per indicare a Quartz di rieseguire il job immediatamente o dopo un ritardo.
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
}
}Caso reale: scheduler con più job
Una configurazione Quartz per la produzione con più job a diverse frequenze, tutti con DI per i servizi.
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 rapida
Che cosa fa l'attributo [DisallowConcurrentExecution] applicato a un job Quartz.NET?
Riepilogo: job pianificati con Quartz.NET
Punti chiave:
- Quartz.NET: scheduler adatto alla produzione con cron, persistenza e clustering
- Definisca i job implementando IJob con un metodo Execute
- Registri il servizio con AddQuartz + AddQuartzHostedService; i job supportano DI
- Formato cron: secondi minuti ore giorno-del-mese mese giorno-della-settimana — tenga presente che i secondi vengono per primi
[DisallowConcurrentExecution]: attende il completamento dell'esecuzione corrente prima di una nuova esecuzione- Utilizzi JobDataMap per passare parametri di runtime ai job
Domande Frequenti
La lezione «Processi pianificati con Quartz.NET» è gratuita?
Sì — il testo completo di «Processi pianificati con Quartz.NET» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «Processi pianificati con Quartz.NET»?
Definisca job e trigger con Quartz.NET, usi espressioni cron e integri il tutto con la DI di ASP.NET Core. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Processi pianificati con Quartz.NET»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- IHostedService e BackgroundService
- Progetti Worker Service
- Attività periodiche e timer
- Processi pianificati con Quartz.NET