0Pricing
C# Academy · Lektion

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.Plugins

Einen 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 expressions

Einfache 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

  1. IHostedService und BackgroundService
  2. Worker-Service-Projekte
  3. Periodische Aufgaben und Timer
  4. Geplante Jobs mit Quartz.NET
← Zurück zu C# Academy