工作中我们经常碰到定时或者固定时间点去做一些事情,然后每天到时间点就会去做这样的事情,如果理解这样的场景,我们就要引入今天我们的主角Quartz,其实这个跟数据库的作业类似,但是不仅仅局限于数据库。

一: quartZ引入&三大核心对象简介

1:在项目中打开Nuget管理,然后搜索QuartZ,现在最新的版本是3.0.7,需要在Framework4.5.2上面使用。

2:quartZ的三大核心对象

A:IScheduler:单元/实例,在这里去完成定时任务的配置,只有单元启动,里面的作业才能正常运行

B:IJob:任务,定时执行动作就是Job

C:ITrigger:定时策略(设置执行的频率或者执行方式)

二:三大核心对象的初始化以及使用如下:

 #region scheduler
Console.WriteLine("初始化scheduler......");
StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
//scheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener());
//scheduler.ListenerManager.AddTriggerListener(new CustomTriggerListener());
//scheduler.ListenerManager.AddJobListener(new CustomJobListener());
await scheduler.Start();
#endregion //IJob ITrigger
{
//创建作业
IJobDetail jobDetail = JobBuilder.Create<TestJob>()
.WithIdentity("testjob", "group1")
.WithDescription("This is TestJob")
.Build(); //IJobDetail jobDetail = JobBuilder.Create<TestStatefulJob>()
// .WithIdentity("testjob", "group1")
// .WithDescription("This is TestJob")
// .Build(); jobDetail.JobDataMap.Add("student1", "Milor");
jobDetail.JobDataMap.Add("student2", "心如迷醉");
jobDetail.JobDataMap.Add("student3", "宇洋");
jobDetail.JobDataMap.Add("Year", DateTime.Now.Year); //ITrigger trigger = TriggerBuilder.Create()
// .WithIdentity("trigger1", "group1")
// .StartNow()
// .WithSimpleSchedule(x => x
// .WithIntervalInSeconds(10)
// .WithRepeatCount(10)
// .RepeatForever())
// .WithDescription("This is testjob's Trigger")
// .Build(); //创建时间策略
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("testtrigger1", "group1")
.StartAt(new DateTimeOffset(DateTime.Now.AddSeconds()))
//.StartNow()//StartAt
.WithCronSchedule("5/10 * * * * ?")//每隔一分钟
//"10,20,30,40,50,0 * * * * ?"
.WithDescription("This is testjob's Trigger")
.Build(); trigger.JobDataMap.Add("student4", "Ray");
trigger.JobDataMap.Add("student5", "心欲无痕");
trigger.JobDataMap.Add("student6", "风在飘动");
trigger.JobDataMap.Add("Year", DateTime.Now.Year + ); await scheduler.ScheduleJob(jobDetail, trigger);
Console.WriteLine("scheduler作业添加完成......");
}
  public class TestJob : IJob
{
public TestJob()
{
Console.WriteLine("This is TestJob的构造。。。");
} public async Task Execute(IJobExecutionContext context)
{
await Task.Run(() =>
{
Console.WriteLine();
Console.WriteLine("*****************************");
{
JobDataMap dataMap = context.JobDetail.JobDataMap;
Console.WriteLine(dataMap.Get("student1"));
Console.WriteLine(dataMap.Get("student2"));
Console.WriteLine(dataMap.Get("student3"));
Console.WriteLine(dataMap.GetInt("Year"));
}
Console.WriteLine($"This is {Thread.CurrentThread.ManagedThreadId} {DateTime.Now}");
//可以换成去数据库查询,可以做啥啥啥
//但是很多情况下,我们也是需要参数的
{
JobDataMap dataMap = context.Trigger.JobDataMap;
Console.WriteLine(dataMap.Get("student4"));
Console.WriteLine(dataMap.Get("student5"));
Console.WriteLine(dataMap.Get("student6"));
Console.WriteLine(dataMap.GetInt("Year"));
}
{
Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
JobDataMap dataMap = context.MergedJobDataMap;
Console.WriteLine(dataMap.Get("student1"));
Console.WriteLine(dataMap.Get("student2"));
Console.WriteLine(dataMap.Get("student3"));
Console.WriteLine(dataMap.Get("student4"));
Console.WriteLine(dataMap.Get("student5"));
Console.WriteLine(dataMap.Get("student6"));
Console.WriteLine(dataMap.GetInt("Year"));
}
Console.WriteLine("*****************************");
Console.WriteLine();
});
}
}

三:任务或者定时策略传参

1:通过定时任务进行传参如下:

然后接收通过:

2:定时策略进行传参:

接收如下:

注意以上两种传参也可以统一通过下面的方式来接收参数,但是如果key相同,则会进行覆盖掉

四:常用的Trigggr

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

  ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds()
.WithRepeatCount()
.RepeatForever()) //从什么时间开始,间隔多久执行重复操作,可以限制最大次数
.WithDescription("This is testjob's Trigger")
.Build();

2:Cron:表达式的方式,可以灵活订制时间规则(具体详情咨询

 ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("testtrigger1", "group1")
.StartAt(new DateTimeOffset(DateTime.Now.AddSeconds()))
//.StartNow()//StartAt
.WithCronSchedule("5/10 * * * * ?")//每隔一分钟 //"10,20,30,40,50,0 * * * * ?"
.WithDescription("This is testjob's Trigger")
.Build();

五:Listener框架的各个环节--事件能做的监听

如果我们自己写定时任务的时候,因为是定时或者周期去做一些事情,所以有时候有问题或者出现了什么故障,我们只能通过我们自己写一下具体的日志,但是Quartz里面的Listener里面内置封装了一些监听接口,分别为:ISchedulerListener,ITriggerListener,IJobListener,里面有一些方法可以让我们去做一下其它的事情,我们下面分别实现了三个接口,代码如下:

1:jobListerer

 public class CustomJobListener : IJobListener
{
public string Name => "CustomJobListener"; public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(()=> {
Console.WriteLine($"CustomJobListener JobExecutionVetoed {context.JobDetail.Description}");
});
} public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() => {
Console.WriteLine($"CustomJobListener JobToBeExecuted {context.JobDetail.Description}");
});
} public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() => {
Console.WriteLine($"CustomJobListener JobWasExecuted {context.JobDetail.Description}");
});
}
}

2:ITriggerListener

 public class CustomTriggerListener : ITriggerListener
{
public string Name => "CustomTriggerListener"; public async Task TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode, CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() =>
{
Console.WriteLine($"CustomTriggerListener TriggerComplete {trigger.Description}");
});
} public async Task TriggerFired(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() =>
{
Console.WriteLine($"CustomTriggerListener TriggerFired {trigger.Description}");
});
} public async Task TriggerMisfired(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() =>
{
Console.WriteLine($"CustomTriggerListener TriggerMisfired {trigger.Description}");
});
} /// <summary>
/// 要不要放弃job
/// </summary>
/// <param name="trigger"></param>
/// <param name="context"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> VetoJobExecution(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() =>
{
Console.WriteLine($"CustomTriggerListener TriggerMisfired {trigger.Description}");
});
return false;//false才能继续执行
}
}

3:ISchedulerListener

 public class CustomSchedulerListener : ISchedulerListener
{
public async Task JobAdded(IJobDetail jobDetail, CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() =>
{
Console.WriteLine($"This is {nameof(CustomSchedulerListener)} JobAdded {jobDetail.Description}");
});
} public Task JobDeleted(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task JobInterrupted(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task JobPaused(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task JobResumed(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task JobScheduled(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task JobsPaused(string jobGroup, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task JobsResumed(string jobGroup, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task JobUnscheduled(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task SchedulerError(string msg, SchedulerException cause, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task SchedulerInStandbyMode(CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task SchedulerShutdown(CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task SchedulerShuttingdown(CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public async Task SchedulerStarted(CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() =>
{
Console.WriteLine($"This is {nameof(CustomSchedulerListener)} SchedulerStarted ");
});
} public async Task SchedulerStarting(CancellationToken cancellationToken = default(CancellationToken))
{
await Task.Run(() =>
{
Console.WriteLine($"This is {nameof(CustomSchedulerListener)} SchedulerStarting ");
});
} public Task SchedulingDataCleared(CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task TriggerFinalized(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task TriggerPaused(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task TriggerResumed(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task TriggersPaused(string triggerGroup, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
} public Task TriggersResumed(string triggerGroup, CancellationToken cancellationToken = default(CancellationToken))
{
throw new NotImplementedException();
}
}

然后通过下面代码来融合到实例中:

  StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
scheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener());
scheduler.ListenerManager.AddTriggerListener(new CustomTriggerListener());
scheduler.ListenerManager.AddJobListener(new CustomJobListener());
await scheduler.Start();

这样就完美的结合在一起了,然后实例,任务,策略每次发生的动作,都会以日志的形式输出来,当然可以记录任何形式的日志。

六:LogProvider可以展示框架运行的一些信息

Quartz.Logging内置了一些记录日志的类,然后需要记录日志的话,可以直接拿来使用,不用自己再去引用配置等记录日志了,下面是自己试着写了一个:

 public class CustomConsoleLogProvider : ILogProvider
{
public Logger GetLogger(string name)
{
return new Logger((level, func, exception, parameters) =>
{
if (level >= LogLevel.Info && func != null)
{
Console.WriteLine($"[{ DateTime.Now.ToLongTimeString()}] [{ level}] { func()} {string.Join(";", parameters.Select(p => p == null ? " " : p.ToString()))} 自定义日志{name}");
}
return true;
});
}
public IDisposable OpenNestedContext(string message)
{
throw new NotImplementedException();
} public IDisposable OpenMappedContext(string key, string value)
{
throw new NotImplementedException();
}
}

然后在DispatcherManager中的init方法中

这样即实现了log的日志

如果想要测试,可以通过:

  static void Main(string[] args)
{
try
{
Console.WriteLine("QuartZ.Net定时调度");
DispatcherManager.Init().GetAwaiter().GetResult();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}

最新文章

  1. WINDOWS下绑定ARP绑定网关
  2. ubuntu14.04编译安装Git2.7
  3. BZOJ 2727 双十字(树状数组)
  4. 从零开始学android开发-通过WebService进行网络编程,使用工具类轻松实现
  5. 50道经典的JAVA编程题 (6-10)
  6. ajax创建对象
  7. Path Sum 解答
  8. (转)ZOJ 3687 The Review Plan I(禁为排列)
  9. 值得赞扬的尝试与进步——CSDN开源夏令营第一印象
  10. RocketMQ初步应用架构理论
  11. asp 自我定时删除
  12. sqlsever存储过程配合代理作业自动定时建表
  13. Centos中MySQL数据的备份和恢复
  14. Icehouse 创建Instance代码分析
  15. 20165235 祁瑛 2018-4 《Java程序设计》第七周学习总结
  16. Object 标签遮挡 Div 显示
  17. nghttp2 和nginx的实践
  18. vs2015打开慢的解决方法
  19. 20155318 2016-2017-2 《Java程序设计》第五周学习总结
  20. Java8中list转map

热门文章

  1. Ultimate Chicken Horse GameProject第二次迭代成果文档
  2. openjdk11 stretch基础镜像无法找到对应openjdk dbg 包的问题
  3. 【day03】Xhtml
  4. java 随笔
  5. CF1187D Subarray Sorting(神奇思路,线段树)
  6. 推荐一款移动端小视频App玲珑视频
  7. python面试题第一份
  8. Qt Quick 多媒体 - 播放音乐和视频
  9. Android studio(AS) svg图片使用
  10. 024 如何让html引用公共的头部和尾部(多个html文件公用一个header.html和footer.html)