Quartz.net動態修改觸發時間

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章