天天看點

Quartz.NET開源作業排程架構系列(四):Plugin Job

  如果在Quartz.NET作業運作時我們想動态修改Job和Trigger的綁定關系,同時修改一些參數那麼該怎麼辦呢?Quartz.NET提供了插件技術,可以通過在XML檔案中對Job和Trigger的參數進行配置,然後定期去加載配置檔案來執行個體化任務和Trigger,這樣就解決了此類問題。

1 PlugInJobExample

下面給出一個示例程式,用插件XML定義的propertie來執行個體化一個ISchedulerFactory,配置檔案名稱用properties["quartz.plugin.jobInitializer.fileNames"] = "quartz_jobs.xml";語句來進行限定。具體示例代碼如下:

using System;
using System.Collections.Specialized;
using System.Threading;
using Common.Logging;
using Quartz;
using Quartz.Impl;
using Quartz.Job;
using System.Windows.Forms;
namespace QuartzDemo
{
    public class PlugInJobExample 
    {
        public string Name
        {
            get { return GetType().Name; }
        }

        public virtual IScheduler Run()
        {
         
            var properties = new NameValueCollection();
            properties["quartz.plugin.triggHistory.type"] = "Quartz.Plugin.History.LoggingJobHistoryPlugin";
            properties["quartz.plugin.jobInitializer.type"] = "Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin";
            //配置檔案名稱
            properties["quartz.plugin.jobInitializer.fileNames"] = "quartz_jobs.xml";
            properties["quartz.plugin.jobInitializer.failOnFileNotFound"] = "true";
            //每隔120秒進行探查,看配置檔案是否更改
            properties["quartz.plugin.jobInitializer.scanInterval"] = "120";

            // 用插件XML定義的propertie來執行個體化一個ISchedulerFactory
            ISchedulerFactory sf = new StdSchedulerFactory(properties);
            IScheduler sched = sf.GetScheduler();

            //啟動
            sched.Start();
            //傳回
            return sched;

        }
    }
}      

2 SimpleJob1

下面給出一個簡單的Job定義,它實作了IJob接口,這裡需要實作Execute(IJobExecutionContext context)方法,它可以更新另外一個視窗的相關資訊。示例代碼如下:

using System;
using System.Collections.Generic;

using Common.Logging;
using Quartz;
using Quartz.Impl;
using Quartz.Job;
using System.Windows.Forms;
namespace QuartzDemo
{

    public class SimpleJob1 : IJob
    {

        public virtual void Execute(IJobExecutionContext context)
        {
            JobKey jobKey = context.JobDetail.Key;
            if (isOpen("FrmConsole"))
            {
                try
                {
                    //擷取目前Form1執行個體
                    __instance = (FrmConsole)Application.OpenForms["FrmConsole"];
                    //擷取目前執行的線程ID
                    __instance.SetInfo(" - "+jobKey + "Thread ID " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());

                    //通過方法更新消息
                    __instance.SetInfo(string.Format(" - {0} exec at {1}",
                    jobKey,
                    System.DateTime.Now.ToString()));

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            // This job simply prints out its job name and the

            if (context.MergedJobDataMap.Count > 0)
            {
                ICollection<string> keys = context.MergedJobDataMap.Keys;
                foreach (string key in keys)
                {
                    String val = context.MergedJobDataMap.GetString(key);
                    __instance.SetInfo(string.Format(" - MergedJobDataMap entry: {0} = {1}", key, val));

                }
            }
            context.Result = "exec ok";
        }

        private static FrmConsole __instance = null;

        /// <summary>
        /// 判斷窗體是否打開
        /// </summary>
        /// <param name="appName"></param>
        /// <returns></returns>
        private bool isOpen(string appName)
        {
            FormCollection collection = Application.OpenForms;
            foreach (Form form in collection)
            {
                if (form.Name == appName)
                {
                    return true;
                }
            }
            return false;
        }
    }
}      

3 xml配置檔案

下面第一個是簡單的Trigger配置,<repeat-interval>1000</repeat-interval>表示間隔時間為1秒,<repeat-count>100</repeat-count>表示循環次數為100次。第二個用的是CronTrigger進行任務定義,周期使用CronExpression進行限定的,如<cron-expression>0/2 * * * * ?</cron-expression>。相關示例代碼如下:

<?xml version="1.0" encoding="UTF-8"?>

<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>jobName1</name>
      <group>jobGroup1</group>
      <description>jobDesciption1</description>
      <job-type>QuartzDemo.SimpleJob1, QuartzDemo</job-type>
      <durable>true</durable>
      <recover>false</recover>
      <job-data-map>
        <entry>
          <key>key0</key>
          <value>value0</value>
        </entry>
        <entry>
          <key>key1</key>
          <value>value1</value>
        </entry>
        <entry>
          <key>key2</key>
          <value>value2</value>
        </entry>
      </job-data-map>
    </job>

    <trigger>
      <simple>
        <name>simpleName</name>
        <group>simpleGroup</group>
        <description>SimpleTriggerDescription</description>
        <job-name>jobName1</job-name>
        <job-group>jobGroup1</job-group>
        <start-time>2015-12-02T10:15:00.0Z</start-time>
        <end-time>2020-05-04T18:13:51.0Z</end-time>
        <misfire-instruction>SmartPolicy</misfire-instruction>
        <repeat-count>100</repeat-count>
        <repeat-interval>1000</repeat-interval>
      </simple>
    </trigger>

  </schedule>

</job-scheduling-data>      
<?xml version="1.0" encoding="UTF-8"?>
<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>SimpleJob1</name>
      <group>myJobGroup1</group>
      <description>SimpleJob1</description>
      <job-type>QuartzDemo.SimpleJob1, QuartzDemo</job-type>
      <durable>true</durable>
      <recover>false</recover>
      <job-data-map>
        <entry>
          <key>author</key>
          <value>jackwangcumt</value>
        </entry>
          <entry>
          <key>blog</key>
          <value>isaboy</value>
        </entry>
        <entry>
          <key>jobType</key>
          <value>XML Plugin Job</value>
        </entry>
      </job-data-map>
    </job>
    <trigger>
      <cron>
        <name>trigger1</name>
        <group>myTriggerGroup</group>
        <job-name>SimpleJob1</job-name>
        <job-group>myJobGroup1</job-group>
        <cron-expression>0/2 * * * * ?</cron-expression>
      </cron>
    </trigger>
  </schedule>
</job-scheduling-data>      

 4 效果

執行示例程式,界面如下:

Quartz.NET開源作業排程架構系列(四):Plugin Job

可以通過修改配置檔案,動态修改任務的相關參數,示範動畫如下圖所示:

Quartz.NET開源作業排程架構系列(四):Plugin Job

繼續閱讀