很多时候,项目需要在不同时刻,执行一个或很多个不同的作业。
Windows执行计划这时并不能很好的满足需求了,迫切需要一个更为强大,方便管理,集群部署的作业调度框架。
Quartz一个开源的作业调度框架,OpenSymphony的开源项目。Quartz.Net 是Quartz的C#移植版本。
它一些很好的特性:
1:支持集群,作业分组,作业远程管理。
2:自定义精细的时间触发器,使用简单,作业和触发分离。
3:数据库支持,可以寄宿Windows服务,WebSite,winform等。
Scheduler 作业调度器。
IJob 作业接口,继承并实现Execute, 编写执行的具体作业逻辑。
JobBuilder 根据设置,生成一个详细作业信息(JobDetail)。
TriggerBuilder 根据规则,生产对应的Trigger
在Nuget管理器中引入quartz
PM> Install-Package Quartz
示例1
static void Main(string[] args)
{
//从工厂中获取一个调度器实例化
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start(); //开启调度器
//==========例子1(简单使用)===========
IJobDetail job1 = JobBuilder.Create() //创建一个作业
.WithIdentity("作业名称", "作业组")
.Build();
ITrigger trigger1 = TriggerBuilder.Create()
.WithIdentity("触发器名称", "触发器组")
.StartNow() //现在开始
.WithSimpleSchedule(x => x //触发时间,5秒一次。
.WithIntervalInSeconds(5)
.RepeatForever()) //不间断重复执行
.Build();
scheduler.ScheduleJob(job1, trigger1); //把作业,触发器加入调度器。
//==========例子2 (执行时 作业数据传递,时间表达式使用)===========
IJobDetail job2= JobBuilder.Create()
.WithIdentity("myJob", "group1")
.UsingJobData("jobSays", "Hello World!")
.Build();
ITrigger trigger2 = TriggerBuilder.Create()
.WithIdentity("mytrigger", "group1")
.StartNow()
.WithCronSchedule("/5 * * ? * *") //时间表达式,5秒一次
.Build();
scheduler.ScheduleJob(job2, trigger2);
//scheduler.Shutdown(); //关闭调度器。
}
声明要执行的作业,HelloJob:
///
/// 作业
///
public class HelloJob : IJob
{
public void Execute(IJobExecutionContext context)
{
Console.WriteLine("作业执行!");
}
}
声明要执行的作业,DumbJob:
public class DumbJob : IJob
{
///
/// context 可以获取当前Job的各种状态。
///
///
public void Execute(IJobExecutionContext context)
{
JobDataMap dataMap = context.JobDetail.JobDataMap;
string content = dataMap.GetString("jobSays");
Console.WriteLine("作业执行,jobSays:" + content);
}
}
示例2
Global.asax
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
namespace SOP
{
public class Global : System.Web.HttpApplication
{
//调度器
IScheduler scheduler;
//调度器工厂
ISchedulerFactory factory;
protected void Application_Start(object sender, EventArgs e)
{
//1、创建一个调度器
factory = new StdSchedulerFactory();
scheduler = factory.GetScheduler();
scheduler.Start(); //开启任务调度
//2、创建一个任务
IJobDetail job = JobBuilder.Create().WithIdentity("job1", "group1").Build();
//3、创建一个触发器
//DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow);
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.WithCronSchedule("0 30 8 * * ?") //每天上午8:30触发
//.StartAt(runTime)
.Build();
//4、将任务与触发器添加到调度器中
scheduler.ScheduleJob(job, trigger);
//scheduler.Shutdown(); //关闭调度器。
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
// 在应用程序关闭时运行的代码
if (scheduler != null)
{
scheduler.Shutdown(true);
}
}
}
}
SecurityThreatTimeJob.cs
using Quartz;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using hpwin;
using System.Collections;
namespace SOP
{
///
/// 时间截止通知
///
public class SecurityThreatTimeJob : IJob
{
public void Execute(IJobExecutionContext context)
{
string sqlSelect = "select * from aqyhgl_yhsb where sjjztz = '2' and zt > '13' and zt < '29' ";
DateTime dTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));//当前时间
DataTable dtSelect = SQLHelper.getDataTable(sqlSelect);
if (dtSelect.Rows.Count > 0)
{
for(int i = 0; i < dtSelect.Rows.Count; i++) //遍历表中的每一条记录
{
DateTime yjwcsj = Convert.ToDateTime(dtSelect.Rows[i]["yjwcsj"].ToString()); //获取预计完成时间
string jdrId = dtSelect.Rows[i]["jdrId"].ToString(); //获取接单人ID
string qx = dtSelect.Rows[i]["qx"].ToString(); //获取责任部门去向编号
string bh = dtSelect.Rows[i]["bh"].ToString(); //获取编号
TimeSpan span = yjwcsj - dTime; //两个时间相减,得到一个 时间间隔 TimeSpan 实例
if (span.TotalDays < 3) // 7天前
{
//获取通知人:领导审核人
DataTable dtDepartment = SQLHelper.getDataTable("select * from aqyhgl_dp where bh = '" + qx + "'");
string ldshrsIds = ""; //领导审核人
if (dtDepartment.Rows.Count > 0)
{
string ldshrs = dtDepartment.Rows[0]["ldshrs"].ToString();
string[] arrShrs = ldshrs.Split(',');
foreach (string arrShr in arrShrs)
{
string id = arrShr.Split('|')[0];
ldshrsIds += (ldshrsIds == "" ? "" : ",") + id;
}
}
//通知人包括:接单人和领导审核人
string tzrIds = ""; //通知人ID
if (!string.IsNullOrEmpty(jdrId))
tzrIds = jdrId;
if (!string.IsNullOrEmpty(ldshrsIds))
tzrIds += (tzrIds == "" ? "" : ",") + ldshrsIds;
//发送消息
if (!string.IsNullOrEmpty(tzrIds))
{
//消息通知
DataTable udt = hpwinbasic.getUsers(tzrIds);
string stitle = "[安全隐患到期提醒通知]";//定义标题
string saffairid = bh;//定义处理id
string pdesc = DateTime.Now.ToString("yyyy - MM - dd HH: mm: ss") + " " + "【" + dtSelect.Rows[i]["yhmc"].ToString() + "】" + "预计完成时间为:" + yjwcsj + ",请尽快处理!";//内容
string linkurl = "http://pt.hpwin.com/sites/market/clients.html?m=1";//定义链接
Messages.MSG_Add(jdrId, udt, "A1011", saffairid, stitle, pdesc, linkurl, true);//发送消息
//更新表中的时间截止通知字段:“1":“已通知”,"2":"未通知"
string upSql = " update aqyhgl_yhsb set sjjztz = '1' where bh = '" + bh + "'";
ArrayList sqlList = new ArrayList();
sqlList.Add(upSql);
SQLHelper.ExecuteNonQuery(sqlList);
}
}
}
}
}
}
}
Quartz.Net官方2.X教程 http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/index.html
Quartz.Net开源地址 https://github.com/quartznet/quartznet
https://blog.csdn.net/u011966339/article/details/79565831
https://www.cnblogs.com/Vincent-yuan/p/10867277.html