很多时候,我们需要把参数传递到作业中,此时有两种情况:
- 普通的参数传递
- 每次作业之间的参数传递
一、普通的参数传递
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");
输出结果:
二、作业之间的参数传递
假如有下面这种情况:
需要将上次作业执行的结果作为参数传递给下次作业,也成为链式传递,就需要使用下面这种方式。
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、创建任务
}
输出结果:
如果按照上面这种方式传递参数,有下面这种特殊情况:
如果第一次任务比较耗时,假如需要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、创建任务
}
输出结果:
从上图可以看出,每次执行的时间间隔时5秒,因为作业中有一句Thread.Sleep(5000),就不是按照之前设置的时间策略3秒去执行的。