天天看点

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

继续阅读