1 What is Quartz.NET?
Docker is a full-featured open-source job scheduling system that can be integrated or used with almost any other software system.
2 Why do I need Quartz.NET?
.NET Framework has "built-in" timer functionality through the System.Timers.Timer class - why would anyone use Quartz instead of these standard functions?
there are many reasons! Here are some:
- Timers have no persistence mechanism.
- The timing of the timer is not flexible (only start time and repeat interval can be set, no information based on date, time of day, etc.).
- Timers do not use a thread pool (one thread per timer)
- There is no real management scheme for timers - you have to write your own mechanism to be able to remember, organize and resume tasks by name, etc.
3 How to use Quartz.NET?
First, install Quartz
Quartz
Then, define a task class
using System; using System.Threading.Tasks; namespace Quartz.ConsoleApp01 { public class HelloJob : IJob { public Task Execute(IJobExecutionContext context) { Console.WriteLine("Hello "+DateTime.Now); return Task.CompletedTask; } } }
Finally, instantiate and start the scheduler, and schedule the job to be executed:
using Quartz.Impl; using System; using System.Threading.Tasks; namespace Quartz.ConsoleApp01 { class Program { static async Task Main(string[] args) { Console.WriteLine("start scheduling!"); //1. Create a schedule var factory = new StdSchedulerFactory(); var scheduler = await factory.GetScheduler(); await scheduler.Start(); //2. Create a task var job = JobBuilder.Create<HelloJob>() .WithIdentity("job1", "group1") .Build(); //3. Create a trigger var trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0/5 * * * * ?") //Execute every 5 seconds .Build(); await scheduler.ScheduleJob(job, trigger); Console.ReadKey(); } } }
Let's take a look at the output:
start scheduling! Hello 2021/1/19 14:37:40 Hello 2021/1/19 14:37:45 Hello 2021/1/19 14:37:50 Hello 2021/1/19 14:37:55
3 Using Quartz.NET using the configuration file method?
First, install Quartz, Quartz.Plugins
Quartz Quartz.Plugins
Then, define a task class
using System; using System.Threading.Tasks; namespace Quartz.ConsoleApp02 { public class HelloJob : IJob { public Task Execute(IJobExecutionContext context) { Console.WriteLine("Hello " + DateTime.Now); return Task.CompletedTask; } } }
Next, configure the quartz_jobs.xml file
<?xml version="1.0" encoding="UTF-8"?> <!-- This file contains job definitions in schema version 2.0 format --> <job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"> <processing-directives> <overwrite-existing-data>true</overwrite-existing-data> </processing-directives> <schedule> <!--TestJob test task configuration--> <job> <name>job1</name> <group>group1</group> <description>job1</description> <job-type>Quartz.ConsoleApp02.HelloJob,Quartz.ConsoleApp02</job-type> <durable>true</durable> <recover>false</recover> </job> <trigger> <cron> <name>trigger1</name> <group>group1</group> <job-name>job1</job-name> <job-group>group1</job-group> <cron-expression>0/5 * * * * ?</cron-expression> </cron> </trigger> </schedule> </job-scheduling-data>
Finally, instantiate and start the scheduler:
using Quartz.Impl; using System; using System.Collections.Specialized; using System.Threading.Tasks; namespace Quartz.ConsoleApp02 { class Program { static async Task Main(string[] args) { Console.WriteLine("start scheduling!"); //1. First, we have to get a reference to the scheduler var properties = new NameValueCollection { ["quartz.scheduler.instanceName"] = "XmlConfiguredInstance", ["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz", ["quartz.threadPool.threadCount"] = "5", ["quartz.plugin.xml.type"] = "Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz.Plugins", ["quartz.plugin.xml.fileNames"] = "~/quartz_jobs.xml", // this is the default ["quartz.plugin.xml.FailOnFileNotFound"] = "true", // this is not the default ["quartz.plugin.xml.failOnSchedulingError"] = "true" }; //2. Create a schedule var factory = new StdSchedulerFactory(properties); var scheduler = await factory.GetScheduler(); await scheduler.Start(); Console.ReadKey(); } } }
4 Cron expressions
4.1 Introduction
cron is a UNIX tool that has been around for a long time, so its scheduling is powerful and proven.
A cron expression consists of 7 segments: second minute hour day month week year (optional)
- "*" is used to select all values in the field, for example "every minute" in the minutes field.
- "?" is useful when you need to specify something in one of the two fields where characters are allowed but not in the other field. For example, if I want the trigger to fire on a specific day of the month (say the 10th), but don't care what day of the week it is, enter the 10 into the "Day of the Month" field, and the ? "Day of the Week" field.
- "-" is used to specify a range. For example, 10-12 means "hours 10, 11 and 12" in the hour field.
- "," is used to specify other values. For example, MON,WED,FRI means "day of the week" in the "day of the week" field.
- "/" is used to specify the increment. For example, 0/15 means "seconds 0, 15, 30 and 45" in the seconds field. and 5/15 in the seconds field means "seconds 5, 20, 35 and 50".
- "L" has different meanings in the two allowed fields. For example, the value in the "L month day" field means "the last day of the month"
- "W" is used to specify the weekday (Monday to Friday) closest to the given date. For example, if you were to specify a value for the "15W month day" field, the meaning would be: "the working day closest to the 15th day of the month".
- "#" is used to specify the "nth" XXX day of the month. For example, the value in the "6#3 Day of the Week" field means "the third Friday of the month" (day 6 = Friday, "#3" = the third Friday of the month).
4.2 Examples
Express | meaning |
---|---|
0 0 12 * * ? | Triggered at 12 noon (noon) every day |
0 15 10 ? * * | Trigger every day at 10:15am |
0 15 10 * * ? | Trigger every day at 10:15am |
0 15 10 * * ? * | Trigger every day at 10:15am |
0 15 10 * * ? 2005 | Fired every day at 10:15am during 2005 |
0 * 14 * * ? | Every day starts at 2pm and ends at 2:59pm, triggering every minute |
0 0/5 14 * * ? | Trigger every 5 minutes every day from 2pm until 2:55pm |
0 0/5 14,18 * * ? | Triggers every 5 minutes starting at 2pm and ending at 2:55pm every day and every 5 minutes starting at 6pm and ending at 6:55pm |
0 0-5 14 * * ? | Every day starts at 2pm and ends at 2:05pm, triggering every minute |
0 10,44 14 ? 3 WED | Triggered every Wednesday in March at 2:10pm and 2:44pm. |
0 15 10 ? * MON-FRI | Triggers every Monday, Tuesday, Wednesday, Thursday and Friday at 10:15 AM |
0 15 10 15 * ? | Triggered at 10:15 am on the 15th of every month |
0 15 10 L * ? | Fires at 10:15 AM on the last day of each month |
0 15 10 L-2 * ? | Fires every month at 10:15 AM on the penultimate |
0 15 10 ? * 6L | Fires at 10:15am on the last Friday of every month |
0 15 10 ? * 6L | Fires at 10:15am on the last Friday of every month |
0 15 10 ? * 6L 2002-2005 | Fired at 10:15am on the last Friday of each month in 2002, 2003, 2004 and 2005 |
0 15 10 ? * 6#3 | Fires every third Friday of the month at 10:15am |
0 0 12 1/5 * ? | Triggers at 12:00 noon (noon) every 5 days of the month starting on the first day of the month. |
0 11 11 11 11 ? | Fires every November 11th at 11:11AM. |