Geplante Jobs mit Quartz.NET
Definieren Sie Jobs und Trigger mit Quartz.NET, verwenden Sie Cron-Ausdrücke und integrieren Sie Quartz.NET in die ASP.NET-Core-DI.
Geplante Jobs mit Quartz.NET ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Warum Quartz.NET?
Wenn Sie Cron-Ausdrücke, die Persistenz von Jobs, Clustering, Wiederholungsrichtlinien und Job-Ketten benötigen, bietet Quartz.NET einen produktionsreifen Scheduler, der über die Möglichkeiten von PeriodicTimer hinausgeht. Es ist die .NET-Portierung des beliebten Java-Schedulers Quartz.
Quartz.NET installieren
Fügen Sie die Pakete Quartz und Quartz.AspNetCore hinzu. Die ASP.NET-Integration registriert den Scheduler automatisch als gehosteten Dienst.
# 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.PluginsEinen Job definieren
Implementieren Sie IJob (oder IAsyncJob in neueren Quartz-Versionen) mit einer Execute-Methode. Der Jobkontext stellt Laufzeitdaten und Informationen zum aktuellen Trigger bereit.
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");
}
}Quartz in ASP.NET Core registrieren
Verwenden Sie AddQuartz, um den Scheduler zu konfigurieren, und AddQuartzHostedService, um ihn als IHostedService auszuführen. Jobs und Trigger werden im Lambda-Ausdruck konfiguriert.
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);Syntax von Cron-Ausdrücken
Quartz verwendet einen Cron-Ausdruck mit 6 oder 7 Feldern: seconds minutes hours day-of-month month day-of-week [year]. Quartz-Cron unterscheidet sich geringfügig von Unix-Cron – die Sekunden stehen an erster Stelle.
// 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 expressionsEinfache Trigger
Für intervallbasierte Zeitpläne ohne die Komplexität von Cron verwenden Sie einfache Trigger mit 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)));JobDataMap
Übergeben Sie Laufzeitparameter über die JobDataMap an Jobs. Greifen Sie innerhalb von Execute über context.JobDetail.JobDataMap darauf zu.
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] verhindert den Start einer neuen Instanz des Jobs, solange eine vorherige Instanz noch ausgeführt wird. Das ist für Jobs, die auf gemeinsam genutzte Ressourcen zugreifen, unerlässlich.
[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.Ausnahmebehandlung und Wiederholung
Umschließen Sie den Jobcode mit try/catch. Wirft der Job JobExecutionException, können Sie Quartz anweisen, den Job sofort oder nach einer Verzögerung erneut auszuführen.
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
}
}Praxisbeispiel: Scheduler mit mehreren Jobs
Eine produktionsreife Quartz-Konfiguration mit mehreren Jobs zu unterschiedlichen Zeitplänen, die alle DI für ihre Dienste verwenden.
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 * * ?"));
});Kurztest
Was bewirkt das Attribut [DisallowConcurrentExecution] bei einem Quartz.NET-Job?
Zusammenfassung: Geplante Quartz.NET-Jobs
Wichtigste Erkenntnisse:
- Quartz.NET: produktionsreifer Scheduler mit Cron, Persistenz und Clustering
- Definieren Sie Jobs durch die Implementierung von IJob mit einer Execute-Methode
- Registrieren Sie Jobs mit AddQuartz + AddQuartzHostedService; sie unterstützen DI
- Cron-Format: seconds minutes hours dom month dow – beachten Sie die Sekunden an erster Stelle
[DisallowConcurrentExecution]: Warten, bis die aktuelle Ausführung beendet ist, bevor der Job erneut ausgeführt wird- Verwenden Sie JobDataMap, um Laufzeitparameter an Jobs zu übergeben
Häufig gestellte Fragen
Ist die Lektion „Geplante Jobs mit Quartz.NET“ kostenlos?
Ja — der vollständige Text von „Geplante Jobs mit Quartz.NET“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Geplante Jobs mit Quartz.NET“?
Definieren Sie Jobs und Trigger mit Quartz.NET, verwenden Sie Cron-Ausdrücke und integrieren Sie Quartz.NET in die ASP.NET-Core-DI. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C# Academy zu starten?
Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „Geplante Jobs mit Quartz.NET“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?
Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- IHostedService und BackgroundService
- Worker-Service-Projekte
- Periodische Aufgaben und Timer
- Geplante Jobs mit Quartz.NET