### GET scheduler context response as JSON Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/http-api Example response from GET {ApiPath}/schedulers/{name}/context, showing all values as strings, with null for null values and invariant text for non-strings. ```json { "context": { "activeFrom": "2025-06-01T12:30:00.0000000+00:00", "nothing": null, "retries": "4352", "tenant": "acme" } } ``` -------------------------------- ### Clone and run the Quartz.NET console tour Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/quick-start.html Clones the Quartz.NET repository, changes to the quartznet directory, and runs the console tour project. The tour presents a menu of thirteen examples; you can pick one or specify it by number, e.g., `-- 5` runs the misfire example. ```bash git clone https://github.com/quartznet/quartznet.git cd quartznet dotnet run --project src/Quartz.Examples ``` -------------------------------- ### Add Microsoft.Extensions.Logging.Console package Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/quick-start.html Installs the package that provides AddSimpleConsole, which is required for the logging setup in the next snippet. ```bash dotnet add package Microsoft.Extensions.Logging.Console ``` -------------------------------- ### Configure Quartz with persistent store and hosted service in Program.cs Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/quick-start.html A complete Program.cs example that sets up a worker service with Quartz, using a SQL Server persistent store with clustering, and schedules HelloJob to run every ten seconds. The hosted service waits for jobs to complete on shutdown. ```csharp HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); builder.AddQuartz(q => { q.ConfigureScheduler(options => options.InstanceName = "MyScheduler"); // default max concurrency is 10 q.UseDefaultThreadPool(maxConcurrency: 5); q.UsePersistentStore(store => { // there are other databases supported too store.UseSqlServer("my connection string"); store.UseClustering(); store.ConfigureStore(options => { // store job data as strings, which avoids surprises when a serialized // type changes shape later options.StoreJobDataAsStrings = true; }); }); // run HelloJob now, and then every ten seconds q.ScheduleJob(trigger => trigger .WithIdentity("helloTrigger") .StartNow() .WithSimpleSchedule(x => x .WithInterval(TimeSpan.FromSeconds(10)) .RepeatForever())); }); builder.AddQuartzHostedService(options => options.WaitForJobsToComplete = true); IHost host = builder.Build(); // blocks until the host stops, and then until the last running job completes await host.RunAsync(); ``` -------------------------------- ### SchedulerMetadata migration diff Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/migration-guide.html Shows the migration from checking metadata.Shutdown, InStandbyMode, and Started to a switch on metadata.Status. This is a diff-style example. ```diff - if (metadata.Shutdown) { … } - else if (metadata.InStandbyMode) { … } - else if (metadata.Started) { … } + switch (metadata.Status) { … } ``` -------------------------------- ### Install Quartz.Serialization.Newtonsoft package Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/json-serialization Adds the Quartz.Serialization.Newtonsoft NuGet package to the project. ```bash dotnet add package Quartz.Serialization.Newtonsoft ``` -------------------------------- ### GET /schedulers JSON response example Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/migration-guide.html Example JSON response from the HTTP API's scheduler listing, which reads ISchedulerRegistry. The status and schedulerInstanceId are null when nothing has built the scheduler, and origin indicates Container or Runtime. ```json { "name": "acme", "schedulerInstanceId": null, "status": null, "origin": "Container" } ``` -------------------------------- ### Configure host with AddQuartz and AddQuartzHostedService Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/tutorial/using-quartz.html Sets up the scheduler to run HelloJob immediately and every 40 seconds, and starts the hosted service with WaitForJobsToComplete. Both methods extend IHostApplicationBuilder, so they also work with WebApplication.CreateBuilder. ```csharp HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); builder.AddQuartz(q => { // run HelloJob now, and then every 40 seconds q.ScheduleJob(trigger => trigger .WithIdentity("helloTrigger") .StartNow() .WithSimpleSchedule(x => x .WithInterval(TimeSpan.FromSeconds(40)) .RepeatForever())); }); builder.AddQuartzHostedService(options => options.WaitForJobsToComplete = true); IHost host = builder.Build(); // blocks until the host is stopped, and then until the last running job completes await host.RunAsync(); ``` -------------------------------- ### Query calendar names and job groups with NameMatcher Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/migration-guide.html Shows how to use NameMatcher (without type parameter) for calendar and group queries, which have bare names. The example queries calendar names starting with 'holiday-' and job groups starting with 'tenant-42-'. ```csharp PagedResult holidays = await scheduler.QueryCalendarNames(new CalendarQuery { Name = NameMatcher.NameStartsWith("holiday-") }); ``` ```csharp PagedResult tenant = await scheduler.QueryJobGroups(new JobGroupQuery { Name = NameMatcher.NameStartsWith("tenant-42-") }); ``` -------------------------------- ### Using WebApplicationFactory to test Quartz host Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/tutorial/testing.html Use AddQuartz and AddQuartzHostedService inside WebApplicationFactory to exercise the real startup path, including configuration binding and hosted-service ordering. Set WaitForJobsToComplete = true on QuartzHostedServiceOptions to avoid teardown racing a running job. Set AwaitApplicationStarted and StartDelay explicitly to control when jobs become eligible. ```csharp await using WebApplicationFactory app = new(); IScheduler scheduler = app.Services.GetRequiredService(); ``` -------------------------------- ### POST {ApiPath}/schedulers/{name}/start?delay=00:00:30 Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/http-api Starts a scheduler with an optional delay. The delay parameter is a TimeSpan in its invariant form, as shown in the example. ```APIDOC ## POST {ApiPath}/schedulers/{name}/start?delay=00:00:30 ### Description Starts a scheduler with an optional delay. The delay parameter is a TimeSpan in its invariant form, as shown in the example. ### Method POST ### Endpoint {ApiPath}/schedulers/{name}/start ### Parameters #### Path Parameters - **name** (string) - Required - The name of the scheduler. #### Query Parameters - **delay** (TimeSpan) - Optional - The delay before the scheduler starts, in invariant TimeSpan format (e.g., "00:00:30"). ### Request Example POST {ApiPath}/schedulers/{name}/start?delay=00:00:30 ``` -------------------------------- ### Configure Quartz and enable HTTP API Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/http-api Sets up the service container with Quartz, the HTTP API, and the hosted service. The order of the calls does not matter because nothing is built until the service provider is created. ```csharp WebApplicationBuilder builder = WebApplication.CreateBuilder(args); builder.AddQuartz(q => { }); builder.Services.AddQuartzHttpApi(); builder.AddQuartzHostedService(options => options.WaitForJobsToComplete = true); ``` -------------------------------- ### Install Quartz and Microsoft.Extensions.Hosting packages Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/hosted-services-integration Adds the Quartz and Microsoft.Extensions.Hosting packages to a console project. The worker and web templates already reference the host, so this is only needed for plain console projects. ```bash dotnet add package Quartz dotnet add package Microsoft.Extensions.Hosting ``` -------------------------------- ### Require authorization for Quartz dashboard Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/how-tos/coming-from-hangfire.html Replaces the commented-out Hangfire dashboard setup. Quartz's dashboard stops the application from starting until the mapping specifies RequireAuthorization or AllowAnonymous. ```csharp // app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = [ ... ] }) app.MapQuartzDashboard().RequireAuthorization("QuartzOperators"); ``` -------------------------------- ### Set trigger-specific misfire threshold Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/tutorial/more-about-triggers.html Shows how to set a trigger-specific misfire threshold using WithMisfireThreshold. The example allows a nightly report to start up to fifteen minutes late. This threshold overrides the store's default for this trigger only. ```csharp // Behind a quota, this report may start up to fifteen minutes late and still be worth running. // Every other trigger keeps the store's threshold. ITrigger report = TriggerBuilder.Create() .WithIdentity("nightly-report") .ForJob("report") .WithCronSchedule("0 0 2 * * ?") .WithMisfireThreshold(TimeSpan.FromMinutes(15)) .Build(); ``` -------------------------------- ### Configure Quartz hosted service with WaitForJobsToComplete Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/hosted-services-integration Example program that configures Quartz and the hosted service. The WaitForJobsToComplete option ensures jobs complete gracefully during shutdown. Requires AddQuartz to be called, otherwise startup throws. ```csharp HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); // see Quartz documentation about how to configure different configuration aspects builder.AddQuartz(q => { // your configuration here }); // Quartz hosting builder.AddQuartzHostedService(options => { // when shutting down we want jobs to complete gracefully options.WaitForJobsToComplete = true; }); await builder.Build().RunAsync(); ``` -------------------------------- ### Install Quartz.HttpClient package Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/http-client.html Adds the Quartz.HttpClient NuGet package to the project. ```bash dotnet add package Quartz.HttpClient ``` -------------------------------- ### PutAsString usage example in C# Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/tutorial/job-data-map Shows how to store DateTimeOffset, TimeSpan, Guid, and int values as strings using PutAsString. Each value is written in an invariant, round-trip format that any store can keep, and can be read back with the matching accessor. ```csharp JobDataMap data = new(); data.PutAsString("runAt", DateTimeOffset.UtcNow); // "O": 2026-08-22T09:15:00.0000000+00:00 data.PutAsString("window", TimeSpan.FromHours(6)); // invariant "06:00:00" data.PutAsString("batchId", Guid.NewGuid()); data.PutAsString("lookbackDays", 30); // any IFormattable ``` -------------------------------- ### Install Quartz.Plugins package Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/quartz-plugins.html Command to add the Quartz.Plugins NuGet package to a project. ```bash dotnet add package Quartz.Plugins ``` -------------------------------- ### HTTP API misfire listing with reasons parameter Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/migration-guide.html The HTTP API's misfire listing now excludes 'Vetoed' rows unless the 'reasons' parameter names them. This example shows a GET request that includes 'Vetoed' in the reasons list. ```http ```http GET /quartz-api/schedulers/QuartzScheduler/history/misfires?reasons=Missed,Overlap,Vetoed ``` ``` -------------------------------- ### Add Quartz as a feature schema in a Marten store Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/weasel.html Adds Quartz tables as a feature schema in Marten, so Marten owns them. Requires ApplyAllDatabaseChangesOnStartup() or db-apply/resources setup before first start. ForScheduler refuses a scheduler that also calls UseWeaselForPostgres(). ```csharp builder.Services.AddMarten(connectionString).ApplyAllDatabaseChangesOnStartup(); // the same tables, with the scheduler's table prefix builder.Services.ConfigureMarten((services, opts) => opts.Storage.Add(QuartzPostgresFeatureSchema.ForScheduler(services))); ``` -------------------------------- ### Install Quartz.AspNetCore package Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/aspnet-core-integration.html Adds the Quartz.AspNetCore NuGet package to the project. ```bash dotnet add package Quartz.AspNetCore ``` -------------------------------- ### ConfigureAllQuartzSchedulers example Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/multi-tenancy.html Shows how to apply a configuration callback to every scheduler in the container, including those registered before or after. The callback adds a plugin and a job listener to each scheduler. Order does not matter; it runs after each scheduler's own callback. Each scheduler gets its own instance of the added parts. ```csharp builder.Services.AddQuartz("acme", q => q.UsePersistentStore(s => s.UseSqlServer(acme))); builder.Services.AddQuartzSchedulers(builder.Configuration.GetSection("Quartz")); // Every scheduler above, and every scheduler registered after this line builder.Services.ConfigureAllQuartzSchedulers(q => { q.AddPlugin(); q.AddJobListener(); }); ``` -------------------------------- ### Install Quartz package Source: https://www.quartz-scheduler.net/documentation/quartz-4.x/packages/microsoft-di-integration Adds the Quartz NuGet package to the project. ```bash dotnet add package Quartz ```