在使用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