An excellent job scheduling framework for Quartz.NET

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.

Posted by vishwavivek on Fri, 03 Jun 2022 12:12:16 +0530