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

C# Quartz结合控制台实现定时任务

程序员文章站 2022-07-05 14:19:27
前言: 你曾经需要应用执行一个任务吗?比如现在有一个需求,需要每天在零点定时执行一些操作,那应该怎样操作呢?这个时候,如果你和你的团队是用.NET编程的话,可以考虑使用Quartz.NET调度器。允许开发人员根据日期间隔来实现任务调度任务。非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定 ......

前言

   你曾经需要应用执行一个任务吗?比如现在有一个需求,需要每天在零点定时执行一些操作,那应该怎样操作呢?这个时候,如果你和你的团队是用.net编程的话,可以考虑使用quartz.net调度器。允许开发人员根据日期间隔来实现任务调度任务。非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。

  quartz一个开源的作业调度框架,是opensymphony 的 quartz api的.net移植,基于c#写成,可应用于winform、asp.net、asp.net core应用中。提供了巨大的灵活性,是一个更为强大,方便管理,集群部署的作业调度框架。

所以,有时候项目需要在不同时刻,执行一个或很多个不同的作业,你可以用它来完成执行创建简单或复杂的任务调度。

导图

C# Quartz结合控制台实现定时任务

特性

1:支持集群,作业分组,作业远程管理。 

2:自定义精细的时间触发器,使用简单,作业和触发分离。

3:数据库支持,可以寄宿windows服务,website,winform等。

概念

scheduler        作业调度器

C# Quartz结合控制台实现定时任务

所有的scheduler都应该由schedulerfactory来创建

 //创建scheduler
            scheduler scheduler = stdschedulerfactory.getdefaultscheduler();

ijob             作业接口,继承并实现execute, 编写执行的具体作业逻辑。

通过实现ijob接口来使你的.net组件可以很简单地被scheduler执行

    public class consolejob : ijob
    {
        public task execute(ijobexecutioncontext context)
        {
            return console.out.writelineasync($"执行作业");
        }
    }

jobbuilder       根据设置,生成一个详细作业信息(jobdetail)。

jobbuilder是一个建造者模式,链式建造。通过静态方法构建一个jobbuilder实例,然后再调用类方法build()创建一个ijobdetail的实现。

public static jobbuilder create(type jobtype)
{
    jobbuilder b = new jobbuilder();
    b.oftype(jobtype);
    return b;
}

triggerbuilder   根据规则,生产对应的trigger,触发器可以规划执行任务

C# Quartz结合控制台实现定时任务

 

通过静态方法构建一个triggerbuilder实例,然后再调用类方法build()创建一个itrigger的实现。

public static triggerbuilder create()
{
    return new triggerbuilder();
}

 根据任务设置触发的开始时间和结束时间

    /// <summary>
    /// 开始时间
    /// </summary>
    /// <param name="starttimeutc"></param>
    /// <returns></returns>
    public triggerbuilder startat(datetimeoffset starttimeutc)
    {
        starttime = starttimeutc;
        return this;
    }
    /// <summary>
    /// 结束时间
    /// </summary>
    /// <param name="endtimeutc"></param>
    /// <returns></returns>
    public triggerbuilder endat(datetimeoffset? endtimeutc)
    {
        endtime = endtimeutc;
        return this;
    }

步骤

1、创建一个ischedulerfactory,然后并且获取 scheduler

2、启动 scheduler

3、创建 job 任务

4、创建 trigger 触发器

5、使用触发器规划执行任务

对应的api

1、ischeduler - 与 scheduler 进行交互的主要接口

2、ijob - 你希望被 scheduler 执行的组件的接口

3、ijobdetail - 用于定义 jobs 实例

4、itrigger - 定义将会在scheduler上执行的 job 上的组件

5、jobbuilder - 用于定义或建立(define/build) jobdetail 实例,jobdetail定义了jobs实例

6、triggerbuilder - 用于定义或建立 trigger 实例

开始

注意

新建一个quartz项目后,需要安装下面的程序包:

你可以用控制台命令的方式安装

install-package quartz

也可以使用下面这种方式选择安装版本

C# Quartz结合控制台实现定时任务

一、创建一个scheduler的引用

            ischedulerfactory schedfact = new stdschedulerfactory();
            ischeduler sched = await schedfact.getscheduler();

二、启动 scheduler:

            await sched.start();

三、实现ijob:

consolejob.cs 实现ijob,在execute方法里编写要处理的业务逻辑,系统就会按照quartz的配置,定时处理

    /// <summary>
    /// 实现ijob,execute方法里编写要处理的业务逻辑
    /// </summary>
    public class consolejob : ijob
    {
        public task execute(ijobexecutioncontext context)
        {
            return console.out.writelineasync($"consolejob执行工作 在当前时间{datetime.now}--上一次执行时间:{datetime.now.addseconds(-5)}");
        }
    }

四、创建trigger:(建立一个某个时间点的触发器,并且每5秒执行一次)

            itrigger trigger = triggerbuilder.create()
                .withidentity("trigger1", "group1")  //触发器 组
                .withsimpleschedule(x => x.withintervalinseconds(5).repeatforever())
                .build();

五、触发器执行任务:

            await sched.schedulejob(job, trigger);

将几个步骤整合后代码如下:

        /// <summary>
        /// 任务调度的使用过程
        /// </summary>
        /// <returns></returns>
        public async static task run()
        {
            // 1.创建scheduler的引用
            ischedulerfactory schedfact = new stdschedulerfactory();
            ischeduler sched = await schedfact.getscheduler();
            

            //2.启动 scheduler
            await sched.start();

            // 3.创建 job
            ijobdetail job = jobbuilder.create<consolejob>()
                    .withidentity("job1", "group1")
                    .build();

            // 4.创建 trigger (创建 trigger 触发器)
            itrigger trigger = triggerbuilder.create()
                .withidentity("trigger1", "group1")  //触发器 组
                .withsimpleschedule(x => x.withintervalinseconds(5).repeatforever())
                .build();

            // 5.使用trigger规划执行任务job (使用触发器规划执行任务)
            await sched.schedulejob(job, trigger);
        }

运行

间隔5秒执行一次后的效果:

C# Quartz结合控制台实现定时任务

附加

这里使用的quartz为3.x 版本,整个版本相对于2.0版本进行了大量的修改,正式支持了.net core 和async/await

引用文章的内容:

3.x 版本的新功能

  • 支持 async/await 基于任务的作业,内部以async/await工作

  • 支持.net core / netstandard 2.0和.net framework 4.5.2及更高版本

  • 通过提供程序名称sqlite-microsoft支持microsoft.data.sqlite,旧的提供程序sqlite也仍然有效,还可以用

  • 增加了对sql server内存优化表的初步支持和quartz.impl.adojobstore.updatelockrowsemaphoremot

  • 从依赖关系中删除common.logging

  • 删除c5 collections,使用.net框架内置的collections

  • 在插件启动时添加对作业调度xml文件的验证

  • 在timezoneutil中添加对额外自定义时区解析器功能的支持

api 不兼容

  • 作业和插件分离到一个单独的程序集/ nuget包里 quartz.jobs和quartz.plugins
  • ado.net提供程序名称已经简化,提供程序名称不带版本,例如sqlserver-20 => sqlserver
  • api方法已经被重新定义,主要使用ireadonlycollection,这隐藏了两个hashsets和list
  • liblog已经隐藏到内部(ilog等),就像它本来打算的那样
  • simplethreadpool 消失了,用系统的线程池取代了
  • 调度程序方法已经改为基于task,记得要await 它们
  • ijob接口现在返回一个task
  • 一些ilist属性已经更改为ireadonlylist ,以正确反映意图
  • sql server ce支持已被删除
  • dailycalendar现在使用日期时间排除日期,并具有iset接口来访问它们
  • iobjectserializer有新的方法,必须实现 void initialize()
  • iinterruptablejob取消了上下文的cancellationtoken

总结

1.其实在实际项目中,可以将上面的方法进行封装处理,形成不同的任务,特别是处理多任务的时候,在不同的job中调用不同的trigger,后续会继续完善开发

2.quartz还有更多的用法,可以参考资料:quartz.net官方文档   和  quartz.net开源地址

3.项目源码地址