.NET 定时任务框架Quartz


theme: smartblue

一、依赖下载

Quartz

image.png

二、基础使用

2.1 创建任务

image.png

 internal class SendMessageJob : IJob
{
    public async Task Execute(IJobExecutionContext context)
    {
        await Task.Run(() =>
        {
            Console.WriteLine("hello:" + DateTime.Now);
        });

    }
}

2.2 任务初始化

image.png

public async static Task Init()
{
    #region 创建单元
    var factory = new StdSchedulerFactory();
    IScheduler task = await factory.GetScheduler();
    await task.Start();
    #endregion

    // job 作业
    IJobDetail jobDetail = JobBuilder.Create<SendMessageJob>()
        .WithIdentity("sendMessageJob","group1")
        .WithDescription("this is send message job")
        .Build();

    // trigger 事件策略
    ITrigger trigger = TriggerBuilder.Create()
        .WithIdentity("sendMessageTriageer", "group")
        .StartNow()
        .WithSimpleSchedule(w=>w.WithIntervalInSeconds(1).WithRepeatCount(3))
        .Build();

    // 将事件策略和作业承载到单元上
    await task.ScheduleJob(jobDetail, trigger);
}

2.3 任务调度

MyFunction.Init().GetAwaiter().GetResult();

image.png

2.4 使用演示

注意,实际运行次数会比要求次数多一次

20231203_161151.gif

三、更多细节

3.1 参数传递

JobDetailTriggerMerged 三种方式

3.1.1 参数提供

image.png

using Quartz;
using Quartz.Impl;
using quartz_01.CustomerJob;

namespace quartz_01
{
    public  class MyFunction
    {
      public async static Task Init()
        {
            #region 创建单元
            var factory = new StdSchedulerFactory();
            IScheduler task = await factory.GetScheduler();
            await task.Start();
            #endregion

            // job 作业
            IJobDetail jobDetail = JobBuilder.Create<SendMessageJob>()
                .WithIdentity("sendMessageJob","group1")
                .WithDescription("this is send message job")
                .Build();

            // 传入参数
            jobDetail.JobDataMap.Add("user1","zhangsan");
            jobDetail.JobDataMap.Add("user2", "lisi");
            jobDetail.JobDataMap.Add("year", DateTime.Now.Year);

            // trigger 事件策略
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("sendMessageTriageer", "group")
                .StartNow()
                .WithSimpleSchedule(w=>w.WithIntervalInSeconds(1))
                .Build();

            // 传入参数
            trigger.JobDataMap.Add("user3", "zhangsan");
            trigger.JobDataMap.Add("user4", "lisi");
            trigger.JobDataMap.Add("year", DateTime.Now.Year + 1);

            // 将事件策略和作业承载到单元上
            await task.ScheduleJob(jobDetail, trigger);
        }

    }
}

3.1.2 参数接收

image.png

using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace quartz_01.CustomerJob
{
    internal class SendMessageJob : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            await Task.Run(() =>
            {
                Object v1 = context.JobDetail.JobDataMap.Get("user1");
                string v2 = context.JobDetail.JobDataMap.GetString("user2");
                int y1 = context.JobDetail.JobDataMap.GetInt("year");

                Object v3 = context.Trigger.JobDataMap.Get("user3");
                string v4 = context.Trigger.JobDataMap.GetString("user4");
                int y2 = context.Trigger.JobDataMap.GetInt("year");

                // 此方法也可取值,当JobDetail和Trigger都存在值时,取后者值覆盖
                // 若两者只有一个有值,则取有值的那个
                int y3 = context.MergedJobDataMap.GetInt("year");

                Console.WriteLine("------- JobDetail --------");
                Console.WriteLine(v1);
                Console.WriteLine(v2);
                Console.WriteLine(y1);
                Console.WriteLine("------- Trigger --------");
                Console.WriteLine(v3);
                Console.WriteLine(v4);
                Console.WriteLine(y2);
                Console.WriteLine("------- Merged --------");
                Console.WriteLine(y3);
            });
            
        }
    }
}

3.1.3 效果演示

image.png

3.1.4 上一次结果为下一次参数

需要添加特性[PersistJobDataAfterExecution]和调用put方法

image.png

效果演示如下:

image.png

3.2 此次任务执行完毕后才可执行下次

3.2.1 当前问题

若此次任务还未执行完毕,就去执行下一次,会导致上一次传递的值失败

如,现在程序每1秒执行一次定时任务,而执行一次需要的时间为3秒,如何需要将上一次的值作为参数传递给下一次,将会传递失败

3.2.2 解决策略

在类上添加特性[DisallowConcurrentExecution]

image.png

3.2.3 效果演示

JobDetail 中的 year 每次执行后都会加一,如图修改成功

20231203_181258.gif

3.3 时间策略

3.3.1 SimpleTriggle

从什么时候开始,间隔多久时间执行重复操作,可以限制最大次数

image.png

3.3.2 Cron

表达式的方式,可以灵活定制时间规则

image.png

可以根据需在线生成:在线Cron表达式生成器 (qqe2.com)

image.png

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值