Quartz框架之参数传递

很多时候,我们需要把参数传递到作业中,此时有两种情况:

  1. 普通的参数传递
  2. 每次作业之间的参数传递

一、普通的参数传递

Quartz框架之参数传递

jobDetail参数传递

          IJobDetail jobdetail = JobBuilder.Create<Job>()
            .WithDescription("This is a job")
            .WithIdentity("Job", "Group1").Build();

        jobdetail.JobDataMap.Add("key_String1", "张三");
        jobdetail.JobDataMap.Add("key_Int1", DateTime.Now.Year);
        jobdetail.JobDataMap.Add("key_Int", DateTime.Now.Year - 1);

trigger参数传递

          trigger.JobDataMap.Add("key_String2", "李四");
        trigger.JobDataMap.Add("key_Int2", DateTime.Now.Year + 1);
        //如果有相同的key(37行),会覆盖掉上面的
        trigger.JobDataMap.Add("key_Int", DateTime.Now.Year + 1);

作业中获取参数

      public async Task Execute(IJobExecutionContext context)
    {
        await Task.Run(() =>
        {
            var string1 = context.JobDetail.JobDataMap.GetString("key_String1");
            var Int1 = context.JobDetail.JobDataMap.GetInt("key_Int1");

            var string2 = context.JobDetail.JobDataMap.GetString("key_String1");
            var Int2 = context.JobDetail.JobDataMap.GetInt("key_Int1");

            //针对重复的key,取最后一个
            var key_int = context.MergedJobDataMap.Get("key_Int");

            Console.WriteLine($"{DateTime.Now} :任务被执行了。。。");
            Console.WriteLine($"{string1} :任务被执行了。。。");
            Console.WriteLine($"{Int1} :任务被执行了。。。");
            Console.WriteLine($"{string2} :任务被执行了。。。");
            Console.WriteLine($"{Int2} :任务被执行了。。。");
            Console.WriteLine($"{key_int} :key_int任务被执行了。。。");
        });
    }

针对有相同key的情况

上面2种方式种同时传递了2次key_int的参数,取最后一次传入的值。
//针对重复的key,取最后一个
var key_int = context.MergedJobDataMap.Get("key_Int");

输出结果:
Quartz框架之参数传递

二、作业之间的参数传递

假如有下面这种情况:
需要将上次作业执行的结果作为参数传递给下次作业,也成为链式传递,就需要使用下面这种方式。
1.引用[PersistJobDataAfterExecution]特性
2. 使用Put函数

/// <summary>
/// 链式传参,上一次任务的结果当作下一次任务的参数传递
/// </summary>
[PersistJobDataAfterExecution]
public class Job : IJob
{
    #region 2、创建任务

    public Job()
    {
        Console.WriteLine("Job被构造了");
    }

    public async Task Execute(IJobExecutionContext context)
    {
        await Task.Run(() =>
        {
            var string1 = context.JobDetail.JobDataMap.GetString("key_String1");
            var Int1 = context.JobDetail.JobDataMap.GetInt("key_Int1");

            var string2 = context.JobDetail.JobDataMap.GetString("key_String1");
            var Int2 = context.JobDetail.JobDataMap.GetInt("key_Int1");

            //针对重复的key,取最后一个
            var key_int = context.MergedJobDataMap.Get("key_Int");

            //将上次的结果加1
            context.JobDetail.JobDataMap.Put("key_Int1", Convert.ToInt32(Int1) +1);

            Console.WriteLine($"{DateTime.Now} :任务被执行了。。。");
            Console.WriteLine($"{string1} :任务被执行了。。。");
            Console.WriteLine($"{Int1} :任务被执行了。。。");
            Console.WriteLine($"{string2} :任务被执行了。。。");
            Console.WriteLine($"{Int2} :任务被执行了。。。");
            Console.WriteLine($"{Int1} :key_Int1任务被执行了。。。");
        });
    }

    #endregion  2、创建任务
}

输出结果:
Quartz框架之参数传递

如果按照上面这种方式传递参数,有下面这种特殊情况:
如果第一次任务比较耗时,假如需要5秒,但是设定的作业执行间隔(w => w.WithIntervalInSeconds(3).WithRepeatCount(3))为3秒,此时就会存在任务执行混乱的情况,针对此种情况,就需要用到DisallowConcurrentExecution特性。

  //假设有下面这种情况
//1、一个任务耗时5秒
//2、但是时间策略是3秒一次(w => w.WithIntervalInSeconds(3).WithRepeatCount(3))
//3、此时就会就会存在任务执行混乱的情况
//4、如果要保证每个任务执行完,才能继续执行下一个任务,就需要用到DisallowConcurrentExecution特性
[DisallowConcurrentExecution]
public class Job2 : IJob
{
    #region 2、创建任务

    public Job2()
    {
        Console.WriteLine("Job2被构造了");
    }

    public async Task Execute(IJobExecutionContext context)
    {
        await Task.Run(() =>
        {
            Thread.Sleep(5000);
            var string1 = context.JobDetail.JobDataMap.GetString("key_String1");
            var Int1 = context.JobDetail.JobDataMap.GetInt("key_Int1");

            var string2 = context.JobDetail.JobDataMap.GetString("key_String1");
            var Int2 = context.JobDetail.JobDataMap.GetInt("key_Int1");

            //针对重复的key,取最后一个
            var key_int = context.MergedJobDataMap.Get("key_Int");

            //将上次的结果加1
            context.JobDetail.JobDataMap.Put("key_Int1", Convert.ToInt32(Int1) + 1);

            Console.WriteLine($"{DateTime.Now} :任务被执行了。。。");
            Console.WriteLine($"{string1} :任务被执行了。。。");
            Console.WriteLine($"{Int1} :任务被执行了。。。");
            Console.WriteLine($"{string2} :任务被执行了。。。");
            Console.WriteLine($"{Int2} :任务被执行了。。。");
            Console.WriteLine($"{Int1} :key_Int1任务被执行了。。。");
        });
    }

    #endregion  2、创建任务
}

输出结果:
Quartz框架之参数传递
从上图可以看出,每次执行的时间间隔时5秒,因为作业中有一句Thread.Sleep(5000),就不是按照之前设置的时间策略3秒去执行的。

上一篇:洛谷 P1020导弹拦截题解


下一篇:P1020-导弹拦截