Quartz 3.13.1
Prefix Reserveddotnet add package Quartz --version 3.13.1
NuGet\Install-Package Quartz -Version 3.13.1
<PackageReference Include="Quartz" Version="3.13.1" />
paket add Quartz --version 3.13.1
#r "nuget: Quartz, 3.13.1"
// Install Quartz as a Cake Addin #addin nuget:?package=Quartz&version=3.13.1 // Install Quartz as a Cake Tool #tool nuget:?package=Quartz&version=3.13.1
layout: default title: Quartz.NET Quick Start Guide
Welcome to the Quick Start Guide for Quartz.NET. As you read this guide, expect to see details of:
- Downloading Quartz.NET
- Installing Quartz.NET
- Configuring Quartz to your own particular needs
- Starting a sample application
Download and Install
You can either download the zip file or use the NuGet package. NuGet package contains only the binaries needed to run Quartz.NET, zip file comes with source code, samples and Quartz.NET server sample application.
NuGet Package
Couldn't get any simpler than this. Just fire up Visual Studio (with NuGet installed) and add reference to package Quartz from package manager extension:
- Right-click on your project's References and choose Manage NuGet Packages...
- Choose Online category from the left
- Enter Quartz to the top right search and hit enter
- Choose Quartz.NET from search results and hit install
- Done!
or from NuGet Command-Line:
Install-Package Quartz
If you want to add JSON Serialization, just add the Quartz.Serialization.Json package the same way.
Zip Archive
Short version: Once you've downloaded Quartz.NET, unzip it somewhere, grab the Quartz.dll
from bin directory and start to use it.
Quartz core library does not have any hard binary dependencies. You can opt-in to more dependencies when you choose to use JSON serialization package, which requires JSON.NET.
You need to have at least Quartz.dll
beside your app binaries to successfully run Quartz.NET. So just add it as a references to your Visual Studio project that uses them.
You can find these dlls from extracted archive from path bin\your-target-framework-version\release\Quartz.
Configuration
This is the big bit! Quartz.NET is a very configurable library. There are two main ways (which are not mutually exclusive) to supply Quartz.NET configuration information:
Fluent Scheduler Builder API
You can configure scheduler using C# fluent API, or via providing NameValueCollection
parameter to scheduler factory
which contains configuration keys and values.
// you can have base properties
var properties = new NameValueCollection();
// and override values via builder
IScheduler scheduler = await SchedulerBuilder.Create(properties)
// default max concurrency is 10
.UseDefaultThreadPool(x => x.MaxConcurrency = 5)
// this is the default
// .WithMisfireThreshold(TimeSpan.FromSeconds(60))
.UsePersistentStore(x =>
{
// force job data map values to be considered as strings
// prevents nasty surprises if object is accidentally serialized and then
// serialization format breaks, defaults to false
x.UseProperties = true;
x.UseClustering();
// there are other SQL providers supported too
x.UseSqlServer("my connection string");
// this requires Quartz.Serialization.Json NuGet package
x.UseJsonSerializer();
})
// job initialization plugin handles our xml reading, without it defaults are used
// requires Quartz.Plugins NuGet package
.UseXmlSchedulingConfiguration(x =>
{
x.Files = new[] { "~/quartz_jobs.xml" };
// this is the default
x.FailOnFileNotFound = true;
// this is not the default
x.FailOnSchedulingError = true;
})
.BuildScheduler();
await scheduler.Start();
Configuration files
Following files are searched for known configuration properties:
YourApplication.exe.config
configuration file using quartz-element (full .NET framework only)appsettings.json
(.NET Core/NET5 onwards)quartz.config
file in your application's root directory (works both with .NET Core and full .NET Framework)
Full documentation of available properties is available in the Quartz Configuration Reference.
To get up and running quickly, a basic quartz.config looks something like this:
quartz.scheduler.instanceName = MyScheduler
quartz.jobStore.type = Quartz.Simpl.RAMJobStore, Quartz
quartz.threadPool.maxConcurrency = 3
Remember to set the Copy to Output Directory on Visual Studio's file property pages to have value Copy always. Otherwise the config will not be seen if it's not in build directory.
The scheduler created by this configuration has the following characteristics:
quartz.scheduler.instanceName
- This scheduler's name will be "MyScheduler".quartz.threadPool.maxConcurrency
- Maximum of 3 jobs can be run simultaneously (default is 10).quartz.jobStore.type
- All of Quartz's data, such as details of jobs and triggers, is held in memory (rather than in a database).Even if you have a database and want to use it with Quartz, I suggest you get Quartz working with the RamJobStore before you open up a whole new dimension by working with a database.
::: tip Actually you don't need to define these properties if you don't want to, Quartz.NET comes with sane defaults :::
Starting a Sample Application
Now you've downloaded and installed Quartz, it's time to get a sample application up and running. The following code obtains an instance of the scheduler, starts it, then shuts it down:
Program.cs
using System;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
namespace QuartzSampleApp
{
public class Program
{
private static async Task Main(string[] args)
{
// Grab the Scheduler instance from the Factory
StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
// and start it off
await scheduler.Start();
// some sleep to show what's happening
await Task.Delay(TimeSpan.FromSeconds(10));
// and last shut down the scheduler when you are ready to close your program
await scheduler.Shutdown();
}
}
}
As of Quartz 3.0 your application will terminate when there's no code left to execute after scheduler.Shutdown()
, because there won't be any active threads. You should manually block exiting of application if you want scheduler to keep running also after the Task.Delay and Shutdown has been processed.
Now running the program will not show anything. When 10 seconds have passed the program will just terminate. Lets add some logging to console.
Adding logging
LibLog can be configured to use different logging frameworks under the hood; namely Log4Net, NLog and Serilog.
When LibLog does not detect any other logging framework to be present, it will be silent. We can configure a custom logger provider that just logs to console show the output if you don't have logging framework setup ready yet.
LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());
private class ConsoleLogProvider : ILogProvider
{
public Logger GetLogger(string name)
{
return (level, func, exception, parameters) =>
{
if (level >= LogLevel.Info && func != null)
{
Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
}
return true;
};
}
public IDisposable OpenNestedContext(string message)
{
throw new NotImplementedException();
}
public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
{
throw new NotImplementedException();
}
}
Trying out the application
Now we should get a lot more information when we start the application.
[12.51.10] [Info] Quartz.NET properties loaded from configuration file 'C:\QuartzSampleApp\quartz.config'
[12.51.10] [Info] Initialized Scheduler Signaller of type: Quartz.Core.SchedulerSignalerImpl
[12.51.10] [Info] Quartz Scheduler created
[12.51.10] [Info] RAMJobStore initialized.
[12.51.10] [Info] Scheduler meta-data: Quartz Scheduler (v3.0.0.0) 'MyScheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'Quartz.Core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'Quartz.Simpl.DefaultThreadPool' - with 3 threads.
Using job-store 'Quartz.Simpl.RAMJobStore' - which does not support persistence. and is not clustered.
[12.51.10] [Info] Quartz scheduler 'MyScheduler' initialized
[12.51.10] [Info] Quartz scheduler version: 3.0.0.0
[12.51.10] [Info] Scheduler MyScheduler_$_NON_CLUSTERED started.
We need a simple test job to test the functionality, lets create HelloJob that outputs greetings to console.
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Console.Out.WriteLineAsync("Greetings from HelloJob!");
}
}
To do something interesting, you need code just after Start() method, before the Task.Delay.
// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
.Build();
// Trigger the job to run now, and then repeat every 10 seconds
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.RepeatForever())
.Build();
// Tell quartz to schedule the job using our trigger
await scheduler.ScheduleJob(job, trigger);
// You could also schedule multiple triggers for the same job with
// await scheduler.ScheduleJob(job, new List<ITrigger>() { trigger1, trigger2 }, replace: true);
The complete console application will now look like this
using System;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Logging;
namespace QuartzSampleApp
{
public class Program
{
private static async Task Main(string[] args)
{
LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());
// Grab the Scheduler instance from the Factory
StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
// and start it off
await scheduler.Start();
// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
.Build();
// Trigger the job to run now, and then repeat every 10 seconds
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.RepeatForever())
.Build();
// Tell quartz to schedule the job using our trigger
await scheduler.ScheduleJob(job, trigger);
// some sleep to show what's happening
await Task.Delay(TimeSpan.FromSeconds(60));
// and last shut down the scheduler when you are ready to close your program
await scheduler.Shutdown();
Console.WriteLine("Press any key to close the application");
Console.ReadKey();
}
// simple log provider to get something to the console
private class ConsoleLogProvider : ILogProvider
{
public Logger GetLogger(string name)
{
return (level, func, exception, parameters) =>
{
if (level >= LogLevel.Info && func != null)
{
Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
}
return true;
};
}
public IDisposable OpenNestedContext(string message)
{
throw new NotImplementedException();
}
public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
{
throw new NotImplementedException();
}
}
}
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Console.Out.WriteLineAsync("Greetings from HelloJob!");
}
}
}
Creating and initializing database
In order to use SQL persistence storage for Quartz and enabling features like clustering, you need to create a database and initialize the schema objects using SQL scripts. First you need to create a database and credentials for Quartz. After you have a database that Quartz will be able to connect to, you also need to create database tables and indexes that Quartz needs for successful operation.
You can find latest DDL scripts in Quartz's GitHub repository and they are also contained in the ZIP archive distribution. There are also thirty party additions to Quartz that enable other types of storage, like NoSQL databases. You can search for them on NuGet.
Now go have some fun exploring Quartz.NET! You can continue by reading the tutorial.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- Microsoft.Extensions.Logging.Abstractions (>= 2.1.1)
-
.NETFramework 4.7.2
- Microsoft.Extensions.Logging.Abstractions (>= 2.1.1)
- System.Diagnostics.DiagnosticSource (>= 4.7.1)
-
.NETStandard 2.0
- Microsoft.Extensions.Logging.Abstractions (>= 2.1.1)
- System.Diagnostics.DiagnosticSource (>= 4.7.1)
-
net6.0
- Microsoft.Extensions.Logging.Abstractions (>= 2.1.1)
NuGet packages (734)
Showing the top 5 NuGet packages that depend on Quartz:
Package | Downloads |
---|---|
Quartz.Extensions.DependencyInjection
Quartz.NET Microsoft.Extensions.DependencyInjection integration; Quartz Scheduling Framework for .NET |
|
Quartz.Serialization.Json
Quartz.NET JSON Serialization Support; Quartz Scheduling Framework for .NET |
|
Quartz.Jobs
Quartz.NET Jobs; Quartz Scheduling Framework for .NET |
|
MassTransit.Quartz
MassTransit Quartz.NET scheduler support; MassTransit provides a developer-focused, modern platform for creating distributed applications without complexity. |
|
Quartz.Plugins.TimeZoneConverter
Quartz.NET TimeZoneConverter integration https://github.com/mj1856/TimeZoneConverter; Quartz Scheduling Framework for .NET |
GitHub repositories (15)
Showing the top 5 popular GitHub repositories that depend on Quartz:
Repository | Stars |
---|---|
bitwarden/server
Bitwarden infrastructure/backend (API, database, Docker, etc).
|
|
abpframework/abp
Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
|
|
aspnetboilerplate/aspnetboilerplate
ASP.NET Boilerplate - Web Application Framework
|
|
kgrzybek/modular-monolith-with-ddd
Full Modular Monolith application with Domain-Driven Design approach.
|
|
MassTransit/MassTransit
Distributed Application Framework for .NET
|
Version | Downloads | Last updated | |
---|---|---|---|
3.13.1 | 230,998 | 11/2/2024 | |
3.13.0 | 1,737,158 | 8/10/2024 | |
3.12.0 | 236,144 | 8/3/2024 | |
3.11.0 | 1,064,487 | 7/7/2024 | |
3.10.0 | 318,493 | 6/26/2024 | |
3.9.0 | 1,642,644 | 5/9/2024 | |
3.8.1 | 2,928,941 | 2/17/2024 | |
3.8.0 | 3,658,714 | 11/18/2023 | |
3.7.0 | 3,369,706 | 8/4/2023 | |
3.6.3 | 1,335,256 | 6/25/2023 | |
3.6.2 | 5,017,735 | 2/25/2023 | |
3.6.1 | 5,791 | 2/25/2023 | |
3.6.0 | 1,315,449 | 1/29/2023 | |
3.5.0 | 5,851,389 | 9/18/2022 | |
3.4.0 | 8,251,041 | 3/27/2022 | |
3.3.3 | 9,998,345 | 8/1/2021 | |
3.3.2 | 3,913,122 | 4/9/2021 | |
3.3.1 | 79,062 | 4/8/2021 | |
3.3.0 | 35,686 | 4/7/2021 | |
3.2.4 | 3,567,578 | 1/19/2021 | |
3.2.3 | 2,402,169 | 10/31/2020 | |
3.2.2 | 529,989 | 10/19/2020 | |
3.2.1 | 21,157 | 10/18/2020 | |
3.2.0 | 284,907 | 10/2/2020 | |
3.1.0 | 1,567,862 | 7/24/2020 | |
3.0.7 | 13,836,574 | 10/7/2018 | |
3.0.6 | 1,863,683 | 7/6/2018 | |
3.0.5 | 479,377 | 5/27/2018 | |
3.0.4 | 926,241 | 3/4/2018 | |
3.0.3 | 68,876 | 2/24/2018 | |
3.0.2 | 455,805 | 1/25/2018 | |
3.0.1 | 50,216 | 1/21/2018 | |
3.0.0 | 466,695 | 12/30/2017 | |
2.6.2 | 1,399,241 | 5/27/2018 | |
2.6.1 | 1,533,837 | 10/9/2017 | |
2.6.0 | 687,974 | 7/30/2017 | |
2.5.0 | 1,437,926 | 2/18/2017 | |
2.4.1 | 1,358,870 | 8/24/2016 | |
2.4.0 | 91,441 | 8/18/2016 | |
2.3.3 | 2,268,730 | 7/9/2015 | |
2.3.2 | 740,997 | 3/30/2015 | |
2.3.1 | 471,319 | 1/15/2015 | |
2.3.0 | 492,341 | 11/8/2014 | |
2.2.4 | 680,418 | 7/27/2014 | |
2.2.3 | 315,357 | 3/30/2014 | |
2.2.2 | 152,627 | 2/9/2014 | |
2.2.1 | 141,856 | 11/24/2013 | |
2.2.0 | 176,903 | 9/9/2013 | |
2.1.2 | 736,284 | 1/13/2013 | |
2.1.1 | 9,186 | 1/4/2013 | |
2.1.0 | 6,177 | 12/31/2012 | |
2.0.1 | 210,684 | 4/22/2012 | |
2.0.0 | 31,686 | 4/9/2012 | |
1.0.3 | 418,136 | 8/3/2011 |