在使用Quartz进行定时任务调度的时候,难免会遇到根据业务需求来修改我们的触发时间,而且是进行动态的修改,接下来我介绍一下Quartz.net怎么动态来修改触发时间,Java中的Quartz也是差不多的原理。这个demo是基于上一次动态暂停、恢复任务的基础上做的,可以查看链接:https://blog.csdn.net/qq_41061437/article/details/100971841
首先建立一个Windows窗口项目,然后通过Nuget引入quartz.net的包,我引入的是2.5.0。接着我们来建立两个任务。
public class Job1:IJob
{
public void Execute(IJobExecutionContext context)
{
Form1.GetInstance().JobList();
MessageBox.Show("第一个Job:" + DateTime.Now.ToString());
}
}
public class Job2:IJob
{
public void Execute(IJobExecutionContext context)
{
Form1.GetInstance().JobList();
MessageBox.Show("第二个Job:" + DateTime.Now.ToString());
}
}
接下来可以写我们的配置文件了,一个quartz_jobs.xml和一个App.config文件:
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<processing-directives>
<overwrite-existing-data>true</overwrite-existing-data>
</processing-directives>
<schedule>
<job>
<!--作业名字,随便取-->
<name>Job1</name>
<!--组名,随便取-->
<group>group1</group>
<!--描述-->
<description>job1</description>
<!--作业类,要定位到我们代码中创建的作业,命名空间.类名-->
<job-type>UpdateQuartzTriggerTime.Job1, UpdateQuartzTriggerTime</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<!--cron表达式触发器-->
<cron>
<!--触发器名字,随便取-->
<name>Trigger1</name>
<!--组名-->
<group>group1</group>
<!--描述-->
<description>trigger</description>
<!--作业名,触发哪个作业-->
<job-name>Job1</job-name>
<!--作业的组名,与作业对应-->
<job-group>group1</job-group>
<misfire-instruction>DoNothing</misfire-instruction>
<cron-expression>0/10 * * * * ?</cron-expression>
</cron>
</trigger>
<job>
<!--作业名字,随便取-->
<name>Job2</name>
<!--组名,随便取-->
<group>group2</group>
<!--描述-->
<description>job2</description>
<!--作业类,要定位到我们代码中创建的作业,命名空间.类名-->
<job-type>UpdateQuartzTriggerTime.Job2, UpdateQuartzTriggerTime</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<!--cron表达式触发器-->
<cron>
<!--触发器名字,随便取-->
<name>Trigger2</name>
<!--组名-->
<group>group2</group>
<!--描述-->
<description>trigger</description>
<!--作业名,触发哪个作业-->
<job-name>Job2</job-name>
<!--作业的组名,与作业对应-->
<job-group>group2</job-group>
<misfire-instruction>DoNothing</misfire-instruction>
<cron-expression>0/10 * * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<quartz>
<add key="quartz.scheduler.instanceName" value="ServerScheduler" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="10" />
<add key="quartz.threadPool.threadPriority" value="2" />
<add key="quartz.plugin.xml.type" value = "Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz" />
<add key="quartz.plugin.xml.fileNames" value = "quartz_jobs.xml" />
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz" />
</quartz>
</configuration>
建立QuartzManage.cs类,其中的Update方法就是我们动态修改时间的核心代码:
class QuartzManage
{
public static string jobName = "";
public static string jobGroupName = "";
public static string triggerName = "";
public static string triggerGroupName = "";
public static Type jobType;
//创建一个调度工厂
public static IScheduler scheduler = GetScheduler();
private static IScheduler GetScheduler()
{
StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
IScheduler scheduler = stdSchedulerFactory.GetScheduler();
return scheduler;
}
public static void Update(string cronTime)
{
//触发器的key
TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroupName);
//建立jobDetail
JobDetailImpl jobDetail = new JobDetailImpl();
jobDetail.Name = jobName;
jobDetail.Group = jobGroupName;
jobDetail.JobType = jobType;
//获取触发器
ITrigger trigger = scheduler.GetTrigger(triggerKey);
CronTriggerImpl cronTriggerImpl = (CronTriggerImpl)trigger;
//移除任务
scheduler.DeleteJob(jobDetail.Key);
//修改时间
cronTriggerImpl.CronExpressionString = cronTime;
//加入任务调度
scheduler.ScheduleJob(jobDetail, cronTriggerImpl);
MessageBox.Show("修改完成!");
Form1.GetInstance().JobList();
}
}
我们来看看我们的主窗体界面布局,我们点击修改时间,弹出另外一个窗口,然后在第二个窗口里面填写cron表达式并最后提交:
其中主窗体界面的代码如下:
public partial class Form1 : Form
{
private static Form1 form1 = new Form1();
public static Form1 GetInstance()
{
return form1;
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
QuartzManage.scheduler.Start();
JobList();
}
private void button1_Click(object sender, EventArgs e)
{
if (QuartzManage.jobName.Equals(""))
{
MessageBox.Show("请先选择要修改的任务!");
}
else
{
Form2 form2 = new Form2();
form2.ShowDialog();
}
}
/// <summary>
/// table展示
/// <summary>
public void JobList()
{
//此方法获取所有的Job的对象
IList<IJobExecutionContext> jobs = QuartzManage.scheduler.GetCurrentlyExecutingJobs();
//此方法获取所有的Job的group的名字
IList<string> name = QuartzManage.scheduler.GetJobGroupNames();
for (int i = 0; i < name.Count; i++)
{
//给jobDataGridView的行赋值,表明多少行
this.dataGridView1.RowCount = name.Count;
//GetJobKeys获取到所有Job的JobKey,相当于Job信息
foreach (JobKey jobKey in QuartzManage.scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(name[i])))
{
this.dataGridView1.Rows[i].Cells[0].Value = jobKey.Name;
this.dataGridView1.Rows[i].Cells[1].Value = jobKey.Group;
this.dataGridView1.Rows[i].Cells[6].Value = QuartzManage.scheduler.GetJobDetail(jobKey).JobType;
}
//GetTriggerKeys获取到所有Trigger的TriggerKey,相当于Trigger信息
foreach (TriggerKey triggerKey in QuartzManage.scheduler.GetTriggerKeys(GroupMatcher<TriggerKey>.GroupEquals(name[i])))
{
//获取触发器的状态
this.dataGridView1.Rows[i].Cells[2].Value = QuartzManage.scheduler.GetTriggerState(triggerKey);
this.dataGridView1.Rows[i].Cells[3].Value = triggerKey.Name;
this.dataGridView1.Rows[i].Cells[4].Value = triggerKey.Group;
//获取下一次触发时间
ICronTrigger cronTrigger = (ICronTrigger)QuartzManage.scheduler.GetTrigger(triggerKey);
CronExpression cronExpression = new CronExpression(cronTrigger.CronExpressionString);
this.dataGridView1.Rows[i].Cells[5].Value = cronExpression.GetNextValidTimeAfter(DateTime.Now).Value.ToLocalTime();
}
}
}
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
QuartzManage.jobName = (string)dataGridView1.SelectedRows[0].Cells["Column1"].Value;
QuartzManage.jobGroupName = (string)dataGridView1.SelectedRows[0].Cells["Column2"].Value;
QuartzManage.triggerName = (string)dataGridView1.SelectedRows[0].Cells["Column4"].Value;
QuartzManage.triggerGroupName = (string)dataGridView1.SelectedRows[0].Cells["Column5"].Value;
QuartzManage.jobType = (Type)dataGridView1.SelectedRows[0].Cells["Column7"].Value;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult result = MessageBox.Show("是否关闭窗口?", "关闭", MessageBoxButtons.YesNo, MessageBoxIcon.None);
if (result == DialogResult.No)
{
e.Cancel = true;
}
else
{
e.Cancel = false;
QuartzManage.scheduler.Shutdown();
}
}
}
点击修改时间按钮,弹出第二个窗口,界面如下:
代码很简单,就是点击提交按钮调用Quartzmanage里面的Update方法即可:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
QuartzManage.Update(textBox1.Text);
}
}
启动项目,可以看到两个都是10秒运行一次:
将第一个修改为5秒运行一次:
资源下载链接:https://download.csdn.net/download/qq_41061437/11796748