using Quartz;
using Quartz.Impl;
using System;
using System.Threading.Tasks;
namespace T.QuartzHelper
{
/// <summary>
/// Quartz任务调度工具类
/// 参考https://www.cnblogs.com/best/p/7658573.html
/// 想避免iis回收,可以写成winfrom放在服务器上,windows任务一直判断程序被关闭就打开执行。
/// </summary>
public class QuartzUtil
{
#region 3.2、创建调度器
/// <summary>
/// 调度器
/// </summary>
private IScheduler scheduler {get; set; }
//调度器工厂
private ISchedulerFactory factory { get; set; }
public QuartzUtil()
{
factory = new StdSchedulerFactory();
scheduler = factory.GetScheduler().Result ;
scheduler.Start();
}
#endregion
/// <summary>
/// 3.3、创建一个任务对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public IJobDetail GetIJobDetail<T>(string name, string group) where T : IJob
{
IJobDetail job = JobBuilder.Create<T>().WithIdentity(name, group).Build();
return job;
}
#region 3.4、创建一个触发器
/// <summary>
/// 3.4、创建一个触发器
/// 计时循环
/// </summary>
/// <param name="name"></param>
/// <param name="group"></param>
/// <param name="cronExpression">"0/5 * * * * ?"=5秒执行一次</param>
/// <returns></returns>
public ITrigger GetTrigger(string name, string group, string cronExpression= "0/5 * * * * ?")
{
return GetTrigger(name, group,null, cronExpression: cronExpression);
}
/// <summary>
/// 3.4、创建一个触发器
/// 定时执行一次
/// </summary>
/// <param name="name"></param>
/// <param name="group"></param>
/// <param name="runTime">开始执行时间</param>
/// <returns></returns>
public ITrigger GetTrigger(string name, string group, DateTimeOffset runTime)
{
return GetTrigger(name, group, runTime,null);
}
/// <summary>
/// 3.4、创建一个触发器
/// </summary>
/// <param name="name"></param>
/// <param name="group"></param>
/// <param name="runTime">定时执行时间</param>
/// <param name="cronExpression">循环执行,"0/5 * * * * ?"=5秒执行一次,更多cron expressions语法:http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/crontrigger.html
/// 由7段构成:秒 分 时 日 月 星期 年(可选)
///"-" :表示范围 MON-WED表示星期一到星期三
///"," :表示列举 MON, WEB表示星期一和星期三
///"*" :表是“每”,每月,每天,每周,每年等
///"/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始
///"?" :只能出现在日,星期段里面,表示不指定具体的值
///"L" :只能出现在日,星期段里面,是Last的缩写,一个月的最后一天,一个星期的最后一天(星期六)
///"W" :表示工作日,距离给定值最近的工作日
///"#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=SUN...6=FRI,7=SAT)
///如果Minutes的数值是 '0/15' ,表示从0开始每15分钟执行
///如果Minutes的数值是 '3/20' ,表示从3开始每20分钟执行,也就是‘3/23/43’
/// </param>
/// <returns></returns>
public ITrigger GetTrigger(string name, string group, DateTimeOffset? runTime, string cronExpression = null)
{
if (runTime == null && string.IsNullOrWhiteSpace(cronExpression))
{
return null;
}
var tri = TriggerBuilder.Create()
.WithIdentity(name, group);
if (runTime != null)
{
tri = tri.StartAt(runTime.Value);
}
if (!string.IsNullOrWhiteSpace(cronExpression))
{
tri = tri.WithCronSchedule(cronExpression);
}
return tri.Build();
}
#endregion
/// <summary>
/// 3.5、将任务与触发器添加到调度器中并执行
/// </summary>
/// <param name="job"></param>
/// <param name="trigger"></param>
public void ScheduleJob(IJobDetail job, ITrigger trigger,bool start=true)
{
//4、将任务与触发器添加到调度器中
scheduler.ScheduleJob(job, trigger);
if (start)
{
//5、开始执行
scheduler.Start();
}
}
/// <summary>
/// 3.6、应用关闭时结束任务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void Shutdown()
{
//在应用程序关闭时运行的代码
if (scheduler != null)
{
scheduler.Shutdown(true);
}
}
}
/// <summary>
/// 3.1、定义要执行的任务
/// </summary>
public class JobTest1 : IJob
{
public Task Execute(IJobExecutionContext context)
{
var task = new Task(() =>
{
Console.WriteLine(DateTime.Now + Environment.NewLine);
////向txt写入当前时间并换行
//System.IO.File.AppendAllText(@"C:\ZTxt\Quartz.txt", DateTime.Now + Environment.NewLine);
});
task.Start();
return task;
}
}
/// <summary>
/// 测试调用
/// </summary>
public class Test1
{
static QuartzUtil qt = new QuartzUtil();
public void Test1Start()
{
//qt.ScheduleJob(qt.GetIJobDetail<JobTest1>("job1", "group1")
// , qt.GetTrigger("job1", "group1", new DateTimeOffset(new DateTime(2020, 9, 28, 16, 19, 00))));
qt.ScheduleJob(qt.GetIJobDetail<JobTest1>("job1", "group1")
, qt.GetTrigger("job1", "group1", "0/5 * * * * ?"));
}
public void End()
{
qt.Shutdown();
}
}
}