Use of Quartz in. NET

Posted by QWERTYtech on Wed, 08 Dec 2021 03:19:47 +0100

1, Background

For example, you need to update or synchronize a data in the database in a certain month of a certain year, or execute part of the code to call the interface at regular intervals, but you don't want to execute it manually

For this kind of business, you can use "timed call task". There are many timed scheduling task frameworks on the market. You can even use timers to make a simple version of task scheduler combined with Windows services. Here we learn Quartz, because Quartz is a powerful, open-source and lightweight task scheduling framework that supports Cron like expressions and other excellent features.

2, Quartz

1. Basic concepts
SchedulerTriggerJob
Scheduler, a stand-alone container when quartz worksTrigger, which defines the time rules for scheduling tasksThe container that invokes the specific action to be performed by the task
2. Preliminary use

1.Nuget introduces QuartZ assembly

2. Create a Scheduler task scheduling container

3. Specify the specific task Job and trigger to be executed

4. Put policies and tasks into the Scheduler and start it

public class QuartzManager
{
    public async static void Init()
    {
        StdSchedulerFactory factory = new StdSchedulerFactory();
        //Create a Scheduler task scheduling container
        IScheduler scheduler = await factory.GetScheduler();
        
        //Specify the specific task Job to be executed
        IJobDetail sendEmailJob = JobBuilder.Create<SendMailJob>()
        .WithIdentity("sendEmailJob", "sendEmailJobGrop")
        .WithDescription("Send mail regularly").Build();
        
        //Set the trigger condition to execute once every five seconds
        ITrigger sendEmailTrigger = TriggerBuilder.Create()
        .WithIdentity("sendEmailTrigger", "sendEmailJobGrop"
        .WithDescription("QuartZ")
        .WithCronSchedule("3/5 * * * * ?") 
        .Build();

        //Put policies and tasks into the Scheduler
        await scheduler.ScheduleJob(sendEmailJob, sendEmailTrigger);
        //Perform tasks
        await scheduler.Start();
    } 
}


//Add features to ensure that tasks do not overlap
[DisallowConcurrentExecution]
public class SendMailJob : IJob
{
    //Job class
    public async Task Execute(IJobExecutionContext context)
    {
        await  Task.Run(() =>
        {
            //doSomthing
            Console.WriteLine($"Start sending mail{DateTime.Now}");
        });
    }
}

3, Transfer parameters

Sometimes we want to need some parameters during Job execution and do some logical processing according to these parameters. At this time, we need to use Quartz to pass parameters.
There are several ways to transfer parameters in Quartz

1.job transfer parameters

2.Trigger parameters

1.job and Trigger parameters

Use JobDataMap.Add to add parameters, and use the JobDataMap.GetString of the context to get the parameters inside the job

IJobDetail sendEmailJob = JobBuilder.Create<SendMailJob>().Build(); 
//Pass a parameter to the Job
sendEmailJob.JobDataMap.Add("params","job Test transmission parameters");

ITrigger trigger = TriggerBuilder.Create().Build();
//Pass a parameter to trigger
trigger.JobDataMap.Add("params", "trigger Test transmission parameters");

//Get parameters in job
public async Task Execute(IJobExecutionContext context)
{
    await  Task.Run(() =>
    {
        //Get job parameters
        string paramJob = context.JobDetail.JobDataMap.GetString("params");
        
        //Get Trigger parameters
        string paramTrigger = context.Trigger.JobDataMap.GetString("params");
        //doSomthing
        Console.WriteLine($"Start sending mail{DateTime.Now}");
    });
}

4, Register listeners in scheduler

Listeners are objects created to perform operations for events that occur in the scheduler. There are mainly three types of listeners

1. The scheduling listener ISchedulerListener is mainly used to listen to the scheduling process.

2. Trigger listener ITriggerListener is mainly used to receive event listening related to triggers.

3. Job listener IJobListener is used to receive event listening related to job operation life cycle.

1. Implement listener

Take the job listener as an example, because triggering is the same implementation as scheduling listening.

1. The custom job listener needs to inherit from the IJobListener interface and implement the method

2. Add a custom listener in the listening management of the scheduler

//Implementation listener
public class CustomJobListener :  IJobListener
{
    public string Name => "CustomJobListener";  
}

//Add to listening management
scheduler.ListenerManager.AddJobListener(new CustomJobListener());

5, Visual management interface

It is used to view the information of the currently running Job by visual tools.

1. You need to create a new web project or console project.

2. In the web project, Nuget introduces Quartz and CrystalQuartz.Remote packages

3. Configure StdSchedulerFactory related information in Job scheduling and specify the listening port

 var properties = new NameValueCollection();
 properties["quartz.scheduler.instanceName"] = "Test Monitor System";

 // Set thread pool
 properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
 properties["quartz.threadPool.threadCount"] = "5";
 properties["quartz.threadPool.threadPriority"] = "Normal";

// Remote output configuration
properties["quartz.scheduler.exporter.type"] = "Quartz.Simpl.RemotingSchedulerExporter, Quartz";
properties["quartz.scheduler.exporter.port"] = "8081";
properties["quartz.scheduler.exporter.bindName"] = "QuartzScheduler";
properties["quartz.scheduler.exporter.channelType"] = "tcp";

var schedulerFactory = new StdSchedulerFactory(properties);
IScheduler _scheduler = await schedulerFactory.GetScheduler();

4. The web monitoring terminal can access the CrystalQuartzPanel.axd under the unified port number to view it.

6, Profile configuration task

In addition to defining various scheduling and triggers of tasks in the code, we can also create Job tasks by using xml configuration files

1. Prepare the configuration file and configure Job+trigger related information. Be sure to set the file attribute to "always copy"

<?xml version="1.0" encoding="UTF-8"?>
<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>
    <job>
      <name>sendEmailJob</name>
      <group>Test Mail Job</group>
      <description>This is Test Mail Job</description>
      <!--Here is Job Class and assembly-->
      <job-type>DispatcherProject.Job.SendMailJob,DispatcherProject</job-type>
      <durable>true</durable>
      <recover>false</recover>
    </job>
    <trigger>
      <cron>
        <name>sendEmailTrigger</name>
        <group>sendEmailJobGrop</group>
        <job-name>sendEmailJob</job-name>
        <job-group>Test Mail Job</job-group>
        <cron-expression>5/3 * * * * ?</cron-expression>
      </cron>
    </trigger>
  </schedule>
</job-scheduling-data>

2. Read the configuration file, obtain the information, and generate the corresponding Job and Trigger

XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(new SimpleTypeLoadHelper());
//Read configuration file
await processor.ProcessFileAndScheduleJobs("~/config/quartz.xml", scheduler);
//Start scheduling task
await scheduler.Start();

Topics: C# .NET