欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用Quartz实现定时作业

程序员文章站 2022-06-28 19:50:31
该文章是系列文章 "基于.NetCore和ABP框架如何让Windows服务执行Quartz定时作业" 的其中一篇。 Quartz是一个开源的作业调度框架,准确的称谓应该是 ,它是Java开源项目 "Quartz Scheduler" 的一部分。 关于Quartz的功能可访问 https://www ......

该文章是系列文章 基于.netcore和abp框架如何让windows服务执行quartz定时作业 的其中一篇。
quartz是一个开源的作业调度框架,准确的称谓应该是 quartz.net,它是java开源项目quartz scheduler的一部分。
关于quartz的功能可访问
nuget地址:https://www.nuget.org/packages/quartz/3.0.7/
github地址:

首先是对定义的myjobservice进行完善。

using system.threading.tasks;

namespace demo.myjob
{
    public class myjobservice
    {
        public async task startasync()
        {
            //操作逻辑
        }

        public async task stopasync()
        {
            //操作逻辑
        }

        public async task continueasync()
        {
            //操作逻辑
        }

        public async task pauseasync()
        {
            //操作逻辑
        }
    }
}

完善之后的代码如下

using system.threading.tasks;
using quartz;
using quartz.impl;

namespace demo.myjob
{
    public class myjobservice
    {
        private readonly task<ischeduler> _defaultscheduler;
        private static ischeduler _scheduler;
        public myjobservice()
        {
            _defaultscheduler = stdschedulerfactory.getdefaultscheduler();
        }
        public async task startasync()
        {
            _scheduler = await _defaultscheduler;
            await _scheduler.start();
        }

        public async task stopasync()
        {
            await _scheduler.shutdown();
        }

        public async task continueasync()
        {
            await _scheduler.resumeall();
        }

        public async task pauseasync()
        {
            await _scheduler.pauseall();
        }
    }
}

ischeduler是主要的接口,它由ischedulerfactory生成,stdschedulerfactory继承自ischedulerfactorystdschedulerfactory获取配置的顺序是先从app.config查找quartz section,没找到就查找文件名为quartz.config的配置,如果再没有,代码内置的有默认的配置项。

使用xml文件配置

quartz.config的简略配置如下

quartz.scheduler.instancename = quartztest
quartz.threadpool.threadcount = 10
quartz.plugin.xml.type = quartz.plugin.xml.xmlschedulingdataprocessorplugin, quartz.plugins
quartz.plugin.xml.filenames = ~/quartz_jobs.xml
  • quartz.scheduler.instancename - 此调度程序的名称将为“quartztest”,如果没配置,默认名称是“quartzscheduler”
  • quartz.threadpool.threadcount - 最多可同时运行10个作业,如果现在有超过10个job需要执行的话,不会报错,但是将有job不能执行。
  • quartz.plugin.xml.type和quartz.plugin.xml.filenames需要新加nuget包quartz.plugins,指定了配置job详情的xml文件,该文件与quartz.config在同级目录下。

注意:新增了三个文件,分别是job_scheduling_data_2_0.xsd、quartz.config、quartz_jobs.xml,文件属性为如果较新则复制

quartz_jobs.xml示例

<?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>sayhellojob</name>
      <group>sayhellojobgroup</group>
      <description>sayhello</description>
      <job-type>demo.myjob.jobs.sayhellojob,demo.myjob</job-type>
      <durable>true</durable>
      <recover>false</recover>
    </job>
    <trigger>
      <cron>
        <name>sayhellojobtrigger</name>
        <group>sayhellojobgroup</group>
        <description>sayhello</description>
        <job-name>sayhellojob</job-name>
        <job-group>sayhellojobgroup</job-group>
        <start-time>2019-06-13t00:00:00+08:00</start-time>
        <cron-expression>0 30 1 * * ?</cron-expression>
      </cron>
    </trigger>
  </schedule>
</job-scheduling-data>

job-type标识加载sayhellojob的名称,要指定正确不然报错。更多配置可以参考:quartz.tests.integration/xml/testdata

实现job

详细文档地址:

ischeduler.start(system.threading.cancellationtoken)调用之后将启动实现的job,该job必须继承ijob,执行的操作放在实现的execute方法中,该方法标识了task,也就是说我们可以在execute方法内调用同步方法或者异步方法。

using system;
using system.threading.tasks;
using quartz;

namespace demo.myjob.jobs
{
    class sayhellojob : ijob
    {
        public async task execute(ijobexecutioncontext context)
        {
            await task.run(() =>
            {
                console.writeline("hello world to async!");
            });
            console.writeline("hello world!");
        }
    }
}