1

Quartz在.NET中的使用

 2 years ago
source link: https://www.cnblogs.com/yuxl01/p/15674125.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

例如需要在某年某月去将数据库的某个数据更新或者同步,又或者是每隔一段时间来执行一部分代码去调用接口,但是又不想人为的手动去执行

针对此类业务可以使用"定时调用任务",市面上有很多的定时调度任务框架,甚至你可以使用定时器来结合Windows服务做一个简易版的任务调度程序,此处我们学习Quartz,因为Quartz是一个强大、开源、轻量级的任务调度框架,支持cron-like表达式其他一些优秀的特性。

二、Quartz

1.基本概念

Scheduler Trigger Job

调度器,quartz工作时的独立容器 触发器,定义了调度任务的时间规则 调用任务具体要执行的动作的容器

2.初步使用

1.Nuget引入QuartZ程序集

2.创建一个Scheduler任务调度容器

3.指定具体执行的任务Job和触发器

4.把策略和任务放入到Scheduler并启动

public class QuartzManager
{
    public async static void Init()
    {
        StdSchedulerFactory factory = new StdSchedulerFactory();
        //创建一个Scheduler任务调度容器
        IScheduler scheduler = await factory.GetScheduler();
        
        //指定具体执行的任务Job
        IJobDetail sendEmailJob = JobBuilder.Create<SendMailJob>()
        .WithIdentity("sendEmailJob", "sendEmailJobGrop")
        .WithDescription("定时发送邮件").Build();
        
        //设置触发条件为五秒执行一次
        ITrigger sendEmailTrigger = TriggerBuilder.Create()
        .WithIdentity("sendEmailTrigger", "sendEmailJobGrop"
        .WithDescription("QuartZ")
        .WithCronSchedule("3/5 * * * * ?") 
        .Build();

        //把策略和任务放入到Scheduler
        await scheduler.ScheduleJob(sendEmailJob, sendEmailTrigger);
        //执行任务
        await scheduler.Start();
    } 
}


//增加特性保证任务不会重叠执行
[DisallowConcurrentExecution]
public class SendMailJob : IJob
{
    //Job类
    public async Task Execute(IJobExecutionContext context)
    {
        await  Task.Run(() =>
        {
            //doSomthing
            Console.WriteLine($"开始发送邮件{DateTime.Now}");
        });
    }
}

三、传递参数

有时候我们想在Job执行时需要一些参数,并根据这些参数来做一些逻辑处理,这时候就需要使用Quartz传参了。
在Quartz中传参主要有一些几种方式

1.job传参

2.Trigger传参

1.job传参和Trigger传参

使用JobDataMap.Add添加参数,在job内部使用上下文的JobDataMap.GetString获取

IJobDetail sendEmailJob = JobBuilder.Create<SendMailJob>().Build(); 
//往Job传一个参数
sendEmailJob.JobDataMap.Add("params","job测试传参");

ITrigger trigger = TriggerBuilder.Create().Build();
//往trigger传一个参数
trigger.JobDataMap.Add("params", "trigger测试传参");

//在job中获取参数
public async Task Execute(IJobExecutionContext context)
{
    await  Task.Run(() =>
    {
        //获取job传参
        string paramJob = context.JobDetail.JobDataMap.GetString("params");
        
        //获取Trigger传参
        string paramTrigger = context.Trigger.JobDataMap.GetString("params");
        //doSomthing
        Console.WriteLine($"开始发送邮件{DateTime.Now}");
    });
}

四、在scheduler中注册监听器

监听器是为调度程序中发生的事件执行操作而创建的对象,主要有一下三种监听器

1.调度监听器ISchedulerListener主要用于调度过程的监听。

2.触发器监听器ITriggerListener主要用于接收和触发器相关的事件监听。

3.作业监听器IJobListener用于接收Job运行生命周期相关事件监听。

1.实现监听器

以作业监听器为例,因为触发和调度监听一样的实现。

1.自定义作业监听器需要继承自IJobListener接口并实现方法.

2.在调度器的监听管理中添加自定义监听器.

//实现监听器
public class CustomJobListener :  IJobListener
{
    public string Name => "CustomJobListener";  
}

//添加到监听管理中
scheduler.ListenerManager.AddJobListener(new CustomJobListener());

五、可视化管理界面

用于可视化工具来查看当前运行Job的信息。

1.需要新建一个web项目或者控制台项目。

2.在web项目中 Nuget 引入Quartz 和CrystalQuartz.Remote程序包

3.在Job调度中配置StdSchedulerFactory相关信息指定监听端口

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

 // 设置线程池
 properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
 properties["quartz.threadPool.threadCount"] = "5";
 properties["quartz.threadPool.threadPriority"] = "Normal";

// 远程输出配置
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.web监控端去访问统一的端口号下的CrystalQuartzPanel.axd即可查看。

image.png

六、配置文件配置任务

我们除了在代码中定义任务的各种调度和触发器之外,还可以使用xml配置文件的方式来创建Job任务

1.准备配置文件,配置Job+trigger相关信息,一定要将此文件属性设为"始终复制"

<?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>
      <!--此处为Job所在的类,及程序集-->
      <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.读取配置文件,获取信息,生成对应的Job和Trigger

XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(new SimpleTypeLoadHelper());
//读取配置文件
await processor.ProcessFileAndScheduleJobs("~/config/quartz.xml", scheduler);
//启动调度任务
await scheduler.Start();

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK