.Net Quartz 定时作业系统
参考地址
Quartz介绍
Quartz 由 作业,触发器,调度器三部分组成
1.作业
- 需要定时执行的作业
2.触发器- 在什么时间触发,推荐使用cron表达式。 在线生成cron表达式: http://cron.qqe2.com/
- 好用的cron表达式生成器,以及查看执行结果
3.调度器- 将作业和触发器装入调度器去执行
1.Nuget 安装Quartz
2.作业 使用
有三种办法创建作业
1.创建一个作业类,然后实现 IJob 接口
创建作业类
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Console.Out.WriteLineAsync("Greetings from HelloJob!");
}
}
引用
//引用作业类
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1") //分组,暂时不知道有什么用
.Build();
2.引用类,适合已经存在的方法动态添加定时作业。//都是需要实现ijob接口
Type type = Type.GetType("test1.TestCase");//获取类 ""里为 命名空间.类名
Object obj = Activator.CreateInstance(type);//这里创建
//4.创建一个作业
IJobDetail job2 = JobBuilder.Create(obj.GetType())
.WithIdentity("demojob1", "groupa")
.Build();
3.引用物理Dll。//都是需要实现ijob接口
//适合在不改变代码的情况下,动态添加要定时执行的方法(前面是文件物理地址(可以使用映射将虚拟地址转换成物理地址) ,后面是命名空间加类名)
object obj = Assembly.LoadFile(@"D:\普通文件袋\测试\ClassLibrary2\bin\Debug\ClassLibrary2.dll").CreateInstance("ClassLibrary2.Class2");
//4.创建一个作业
IJobDetail job2 = JobBuilder.Create(obj.GetType())
.WithIdentity("demojob1", "groupa")
.Build();
3.触发器 使用
/// <summary>
/// 周一到周五,每天早晨8点30
/// </summary>
/// <returns></returns>
public static ITrigger DayMorningRun()
{
string corn = "0 30 8 ? * MON-FRI";
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger_DayMorningRun", "group_DayMorningRun")
.WithCronSchedule(corn)
.Build();
return trigger;
}
2.可以一个触发器调多个作业
string corn = "3/5 * * * * ? *";
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("demotrigger1", "groupa")
.WithCronSchedule(corn)//从第三秒开始,每5秒执行一次
.ForJob(job) //触发器绑定多个作业
.ForJob(job) //触发器绑定多个作业
.Build();
4.调度器 使用
官方示例
https://www.quartz-scheduler.net/documentation/quartz-3.x/quick-start.html
private static async Task RunProgramRunExample()
{
try
{
//1.首先创建一个作业调度池
ISchedulerFactory schedf = new StdSchedulerFactory();
//2.实例化调度器工厂
ISchedulerFactory schedulefactory = new StdSchedulerFactory();
//3.实例化调度器
IScheduler scheduler = await schedulefactory.GetScheduler();
// 开始执行调度
await scheduler.Start();
//将作业以及触发器放入调度器
await scheduler.ScheduleJob(job, trigger);
//也可以放入触发器
//await scheduler.ScheduleJob(trigger);
// some sleep to show what's happening
//await Task.Delay(TimeSpan.FromSeconds(10)); //程序10秒后执行下一步
//await scheduler.Shutdown(); //结束调度
}
catch (SchedulerException se)
{
Console.WriteLine(se);
}
}
5.完整示例
class Program
{
private static void Main(string[] args)
{
RunProgramRunExample().GetAwaiter().GetResult();
Console.WriteLine("Press any key to close the application");
Console.ReadKey();
}
private static async Task RunProgramRunExample()
{
try
{
//1.首先创建一个作业调度池
ISchedulerFactory schedf = new StdSchedulerFactory();
//2.实例化调度器工厂
ISchedulerFactory schedulefactory = new StdSchedulerFactory();
//3.实例化调度器
IScheduler scheduler = await schedulefactory.GetScheduler();
await scheduler.Start();
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
.Build();
string corn = "3/5 * * * * ? *";
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("demotrigger1", "groupa")
.WithCronSchedule(corn)//从第三秒开始,每5秒执行一次
.Build();
await scheduler.ScheduleJob(job, trigger);
}
catch (SchedulerException se)
{
Console.WriteLine(se);
}
}
}
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Console.Out.WriteLineAsync("Greetings from HelloJob!");
}
}
6.Mvc 扩展
MVC分别配置了三个类,CronJobs 定时作业,CronTriggers 触发器,CronSchedulers 调度器
//todo,可以将触发器里面直接放入定时作业。这个后期再优化吧
最后需要在 Global.asax 的Application_Start 里面注册
定时作业 CronJobs
public class CronJobs
{
public class Job : IJob
{
public async Task Execute(IJobExecutionContext context)
{
Task task1 = Task.Run(() =>
{
//执行定时作业
});
//或者这边也行
}
}
}
触发器,CronTriggers
public class CronTriggers
{
//在线生成cron表达式: http://cron.qqe2.com/
/// <summary>
/// 周一到周五,每天早晨8点30
/// </summary>
/// <returns></returns>
public static ITrigger DayMorningRun()
{
string corn = "0 30 8 ? * MON-FRI";
ITrigger trigger = TriggerBuilder.Create()
//.WithIdentity("trigger_DayMorningRun", "group_DayMorningRun")
.WithCronSchedule(corn)
.Build();
return trigger;
}
}
调度器 CronSchedulers
public class CronSchedulers
{
public static void Start()
{
//Task task = Task.Run(async () => {
// await StartAsync();
//});
StartAsync().GetAwaiter().GetResult();
}
public static async Task StartAsync()
{
try
{
//1.首先创建一个作业调度池
ISchedulerFactory schedf = new StdSchedulerFactory();
//2.实例化调度器工厂
ISchedulerFactory schedulefactory = new StdSchedulerFactory();
//3.实例化调度器
IScheduler scheduler = await schedulefactory.GetScheduler();
await scheduler.Start();
IJobDetail job1 = JobBuilder.Create<CronJobs.DayMorningRunJobs>()
.Build();
ITrigger trigger1 = CronTriggers.DayMorningRun();
//单个触发器只能触发单个作业,单个作业可以多个触发器触发
await scheduler.ScheduleJob(job1, trigger1);
}
catch (SchedulerException se)
{
LogHelper.WriteLog("调度报错", se);//log4Net日志
}
}
}
在 Global.asax 的Application_Start 里面注册
//定时调度
CronSchedulers.Start();