Quartz网页笔记整理 与 QuartzHelper实例

0.Quartz.NET 3.x Tutorial

Quartz.NET - Quartz.NET 3.x Tutorial

1.简单的Quartz例子调用

Quartz.NET实现作业调度

2.Quartz的调度框架,包含可视化的界面的简单使用

Quartz.net 开源job调度框架(一)

 3.CronTrigger Tutorial

Quartz.NET - CronTrigger Tutorial

4.CrystalQuartz

Net作业调度(二) -CrystalQuartz远程管理

 

5.Quartz Instance

5.1 Clinet

5.1.1 使用到的相关实体定义

[Description("触发器基础信息类")]
    public class TriggerModel
    {
        #region CommonInfo
        /// <summary>
        /// 触发器名称
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// 触发器所在组
        /// </summary>
        public string group { get; set; }

        /// <summary>
        /// 触发器描述
        /// </summary>
        public string description { get; set; }

        /// <summary>
        /// 触发器开始执行时间
        /// </summary>
        public string startTime { get; set; }

        /// <summary>
        /// 触发器结束执行时间
        /// </summary>
        public string endTime { get; set; }

        /// <summary>
        /// 触发器所使用的日历过滤器
        /// </summary>
        public string calendarName { get; set; }

        /// <summary>
        /// 触发器下次执行时间
        /// </summary>
        public string nextFireTime { get; set; }

        /// <summary>
        /// 触发器上次执行时间
        /// </summary>
        public string previousFireTime { get; set; }

        /// <summary>
        /// 触发器的触发规则
        /// </summary>
        public string rule { get; set; }

        /// <summary>
        /// 触发器触发次数
        /// </summary>
        public int? timesTriggered { get; set; }

        /// <summary>
        /// 触发器类型
        /// </summary>
        public string triggerType { get; set; }

        /// <summary>
        /// 触发器状态(Normal = 0,Paused = 1,Complete = 2,Error = 3,Blocked = 4,None = 5,)
        /// </summary>
        public int triggerState { get; set; }

        /// <summary>
        /// 关联Job组名
        /// </summary>
        public string jobDetailGroup { get; set; }

        /// <summary>
        /// 关联Job组名
        /// </summary>
        public string jobDetailName { get; set; }

        #endregion

        #region SimpleTrigger
        /// <summary>
        /// 触发器重复执行次数
        /// </summary>
        public int repeatCount { get; set; }

        /// <summary>
        /// 触发器执行周期
        /// </summary>
        public string repeatInterval { get; set; }

        #endregion

        #region DailyTimeTrigger
        /// <summary>
        /// 日常触发器每天开始触发时间
        /// </summary>
        public string startTimeOfDay { get; set; }

        /// <summary>
        /// 日常触发器每天结束触发时间
        /// </summary>
        public string endTimeOfDay { get; set; }

        /// <summary>
        /// 周中天
        /// </summary>
        public string daysOfWeek { get; set; }
        #endregion

        #region CronTrigger
        /// <summary>
        /// Cron表达式
        /// </summary>
        public string cronExpression { get; set; }
        #endregion
    }

    /// <summary>
    /// Trigger操作类
    /// </summary>
    public class TriggerOperateModel
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string name { get; set; }

        /// <summary>
        ////// </summary>
        public string group { get; set; }

        /// <summary>
        /// 操作类型
        /// </summary>
        public int operateType { get; set; }
    }
   public class JobMapModel
    {
        public string key { get; set; }

        public string value { get; set; }
    }
 [Description("作业信息类")]
    public class JobModel
    {
        /// <summary>
        /// 作业所在组
        /// </summary>     
        public string group { get; set; }

        /// <summary>
        /// 作业名称
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// 作业描述
        /// </summary>
        public string description { get; set; }

        /// <summary>
        /// 作业类型
        /// </summary>
        public string type { get; set; }

        /// <summary>
        /// 作业是否允许孤立存在
        /// </summary>
        public bool durable { get; set; }

        /// <summary>
        /// 工作数据字段
        /// </summary>
        public List<JobMapModel> jobDataMap { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public bool requestsRecovery { get; set; }

        /// <summary>
        /// 并发控制
        /// </summary>
        public bool concurrentExecutionDisallowed { get; set; }

        /// <summary>
        /// 执行后JobData数据是否能持久
        /// </summary>
        public bool persistJobDataAfterExecution { get; set; }

        /// <summary>
        /// 与JobInfo关联的所有TriggerInfos
        /// </summary>
        public List<TriggerModel> triggerInfos { get; set; }

    }
 public class JobTriggerModel
    {
        /// <summary>
        /// 作业名称
        /// </summary>
        public string jobName { get; set; }


        /// <summary>
        /// 触发器名称
        /// </summary>
        public string triggerName { get; set; }

        /// <summary>
        /// 触发器所在组
        /// </summary>     
        public string triggerGroup { get; set; }

        /// <summary>
        /// 触发器开始执行时间
        /// </summary>
        public string startTime { get; set; }

        /// <summary>
        /// 触发器结束执行时间
        /// </summary>
        //public string endTime { get; set; }


        /// <summary>
        /// 触发器下次执行时间
        /// </summary>
        public string nextFireTime { get; set; }

        /// <summary>
        /// 触发器上次执行时间
        /// </summary>
        public string previousFireTime { get; set; }
    }

5.1.2 Quartz帮助类

using Quartz;
using Quartz.Impl;
using Quartz.Impl.Matchers;
using Quartz.Impl.Triggers;
using Models.QuartzTimedTask;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

public class QuartzHelper
    {
        #region SchedulerOperate

        /// <summary>
        /// 创建Scheduler实例
        /// </summary>
        /// <returns></returns>
        public IScheduler CreateScheduler()
        {
            ISchedulerFactory schedulerFactory = new StdSchedulerFactory();

            return schedulerFactory.GetScheduler();
        }

        #endregion


        #region private

        private bool AddOrEditJobDetail(JobModel jobInfo, bool isReplace)
        {
            var result = false;
            var scheduler = CreateScheduler();


            //job
            var jobDetail = QuartzConvert.JobInfoToJobDetailImpl(jobInfo);
            var isCheckExistsOk = scheduler.CheckExists(jobDetail.Key);
            isCheckExistsOk = isReplace ? !isCheckExistsOk : isCheckExistsOk;
            if (jobDetail == null || isCheckExistsOk) return false;

            //add job
            scheduler.AddJob(jobDetail, isReplace, !jobDetail.Durable);
            result = scheduler.CheckExists(jobDetail.Key);

            return result;
        }

        #endregion


        /// <summary>
        /// 添加新的JobDetail
        /// </summary>
        /// <param name="jonInfo"></param>
        /// <returns></returns>
        public bool AddNewJobDetail(JobModel jobInfo)
        {
            return AddOrEditJobDetail(jobInfo, false);
        }

        /// <summary>
        /// 编辑JobDetail
        /// </summary>
        /// <param name="jonInfo"></param>
        /// <returns></returns>
        public bool EditJobDetail(JobModel jobInfo)
        {
            return AddOrEditJobDetail(jobInfo, true);
        }

        /// <summary>
        /// 删除JobDetail
        /// </summary>
        /// <param name="name"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public bool DeleteJobDetail(string name, string group)
        {
            var scheduler = CreateScheduler();

            var ifExecute =
                scheduler.GetCurrentlyExecutingJobs()
                    .Select(z => z.JobDetail)
                    .Where(z => z.Key.Name == name && z.Key.Group == group)
                    .ToList()
                    .Count > 0;

            if (ifExecute) return false;

            var result = scheduler.DeleteJob(new JobKey(name, group));

            return result;
        }


        #region trigger

        /// <summary>
        /// 添加Trigger
        /// </summary>
        /// <param name="triggerInfo"></param>
        /// <returns></returns>
        public bool AddNewTriggerWithJobDetail(TriggerModel triggerInfo)
        {
            var scheduler = CreateScheduler();

            var trigger = scheduler.GetTrigger(new TriggerKey(triggerInfo.name, triggerInfo.group));
            if (trigger != null) return false;

            var job = scheduler.GetJobDetail(new JobKey(triggerInfo.jobDetailName, triggerInfo.jobDetailGroup));
            if (job == null) return false;

            trigger = QuartzConvert.TriggerInfoToCronTrigger(triggerInfo);
            if (trigger == null) return false;

            var abstractTrigger = trigger as AbstractTrigger;
            if (abstractTrigger == null) return false;

            abstractTrigger.JobKey = job.Key;
            scheduler.ScheduleJob(abstractTrigger);
            abstractTrigger.StartTimeUtc = abstractTrigger.StartTimeUtc.AddSeconds(1);
            scheduler.PauseTrigger(abstractTrigger.Key);

            return true;
        }

        public bool DeleteTrigger(string name, string group)
        {
            var scheduler = CreateScheduler();

            var ifExecute =
                scheduler.GetCurrentlyExecutingJobs()
                    .Select(z => z.Trigger)
                    .Where(z => z.Key.Name == name && z.Key.Group == group)
                    .ToList()
                    .Count > 0;

            if (ifExecute) return false;

            var result = scheduler.UnscheduleJob(new TriggerKey(name, group));

            return result;
        }

        public void PauseTrigger(TriggerOperateModel operate)
        {
            var scheduler = CreateScheduler();
            if (scheduler == null) scheduler = CreateScheduler();
            if (operate.operateType != 0 && operate.operateType != 1) return;
            scheduler.PauseTrigger(new TriggerKey(operate.name, operate.group));
        }

        public void ResumeTrigger(TriggerOperateModel operate)
        {
            var scheduler = CreateScheduler();
            if (scheduler == null) scheduler = CreateScheduler();
            if (operate.operateType != 0 && operate.operateType != 1) return;
            scheduler.ResumeTrigger(new TriggerKey(operate.name, operate.group));
        }


        //<summary>
        //根据JobDetail获取
        //</summary>
        //<param name="jobKey"></param>
        //<returns></returns>
        public List<TriggerModel> GetTriggerInfosByJobDetail(JobKey jobKey)
        {
            var scheduler = CreateScheduler();
            var triggers = scheduler.GetTriggersOfJob(jobKey).ToList();
            var triggerInfos = new List<TriggerModel>();

            triggers.ForEach(z =>
            {
                var trigger = QuartzConvert.CronTriggerImplToTriggerInfo((CronTriggerImpl)z);
                if (trigger == null) return;
                trigger.triggerState = (int)scheduler.GetTriggerState(z.Key);
                triggerInfos.Add(trigger);
            });

            return triggerInfos;
        }

        #endregion


        /// <summary>
        /// 获取所有任务
        /// </summary>
        /// <returns></returns>
        public List<JobModel> GetAllJobDetails()
        {
            var result = new List<JobModel>();
            var scheduler = CreateScheduler();
            var groupNameList = scheduler.GetJobGroupNames();

            foreach (var groupName in groupNameList)
            {
                var jobKeyList = scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(groupName)).ToList();
                foreach (var jobKey in jobKeyList)
                {
                    var jobDetail = scheduler.GetJobDetail(jobKey) as JobDetailImpl;
                    result.Add(QuartzConvert.JobDetailImplToJobInfo(jobDetail, this));
                }
            }

            return result;
        }


        public List<JobTriggerModel> GetJobTriggerList()
        {
            var result = new List<JobTriggerModel>();
            var scheduler = CreateScheduler();
            var groupNameList = scheduler.GetTriggerGroupNames();
            foreach (var groupName in groupNameList)
            {
                var triggerKeyList = scheduler.GetTriggerKeys(GroupMatcher<TriggerKey>.GroupEquals(groupName));

                foreach (var triggerKey in triggerKeyList)
                {
                    var triggerDetail = scheduler.GetTrigger(triggerKey) as CronTriggerImpl;
                    var jobTrigger = QuartzConvert.CronTriggerImplToJobTriggerModel(triggerDetail);
                    result.Add(jobTrigger);
                }
            }
            return result;
        }

        /// <summary>
        /// 立即执行一次
        /// </summary>
        /// <param name="jobKey"></param>
        public void ExcuteJobNow(string name, string group)
        {
            var scheduler = CreateScheduler();
            var jobKey = new JobKey(name, group);
            var jobDetail = scheduler.GetJobDetail(jobKey);
            var excuteNowTrigger = TriggerBuilder.Create().WithIdentity("ExcuteNowTrigger", "ExcuteNowGroup").ForJob(jobDetail).StartNow().Build();
            scheduler.ScheduleJob(excuteNowTrigger);
        }
    }
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using QuartzTimedTaskJobs;
using QuartzTimedTask.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

 public class QuartzConvert
    {
        private static Type JobType = typeof(FireTimingTaskJob);

        /// <summary>
        /// JobInfo转JobDetail
        /// </summary>
        /// <param name="jobInfo"></param>
        /// <returns></returns>
        public static JobDetailImpl JobInfoToJobDetailImpl(JobModel jobInfo)
        {
            var jobDetail = new JobDetailImpl
            {
                Name = jobInfo.name,
                Group = jobInfo.group,
                Key = new JobKey(jobInfo.name, jobInfo.group),
                Description = jobInfo.description,
                JobType = JobType,
                RequestsRecovery = jobInfo.requestsRecovery,
                Durable = jobInfo.durable
            };

            if (jobInfo.jobDataMap != null && jobInfo.jobDataMap.Count > 0)
            {
                jobInfo.jobDataMap.ForEach(z =>
                {
                    jobDetail.JobDataMap.Add(z.key, z.value);
                });
            }

            return jobDetail;
        }

        /// <summary>
        /// TriggerModel转CronTriggerImpl(只支持CronTriggerImpl)
        /// </summary>
        /// <param name="triggerInfo"></param>
        /// <returns></returns>
        public static CronTriggerImpl TriggerInfoToCronTrigger(TriggerModel triggerInfo)
        {
            var cronTrigger = new CronTriggerImpl
            {
                Name = triggerInfo.name,
                Group = triggerInfo.group,
                CalendarName = triggerInfo.calendarName,
                Description = triggerInfo.description,
                CronExpressionString = CronExpression.IsValidExpression(triggerInfo.cronExpression) ? triggerInfo.cronExpression : "",
            };

            #region [StartTime\EndTime]-Operate

            DateTime startTime, endTime;
            var ifsuccess = DateTime.TryParse(triggerInfo.startTime, out startTime);
            if (!ifsuccess) startTime = DateTime.Now;
            cronTrigger.StartTimeUtc = startTime;
            ifsuccess = DateTime.TryParse(triggerInfo.endTime, out endTime);
            if (ifsuccess) cronTrigger.EndTimeUtc = endTime;

            #endregion

            return cronTrigger;
        }

        public static JobModel JobDetailImplToJobInfo(JobDetailImpl jobDetailImpl, QuartzHelper qh)
        {
            var jobInfo = new JobModel
            {
                name = jobDetailImpl.Name,
                group = jobDetailImpl.Group,
                description = jobDetailImpl.Description,
                type = jobDetailImpl.JobType.Name,
                requestsRecovery = jobDetailImpl.RequestsRecovery,
                durable = jobDetailImpl.Durable,
                concurrentExecutionDisallowed = jobDetailImpl.ConcurrentExecutionDisallowed,
                persistJobDataAfterExecution = jobDetailImpl.PersistJobDataAfterExecution,
                jobDataMap = new List<JobMapModel>(),
            };

            //if (jobDetailImpl.JobDataMap != null && jobDetailImpl.JobDataMap.Count > 0)
            //{
            //    jobDetailImpl.JobDataMap.ForEach(z =>
            //    {
            //        jobInfo.jobDataMap.Add(new JobMapModel { key = z.Key, value = z.Value.ToString() });
            //    });
            //}

            jobInfo.triggerInfos = qh.GetTriggerInfosByJobDetail(jobDetailImpl.Key);

            return jobInfo;
        }

        /// <summary>
        /// CronTriggerImpl转TriggerInfo
        /// </summary>
        /// <param name="cronTriggerImpl"></param>
        /// <returns></returns>       
        public static TriggerModel CronTriggerImplToTriggerInfo(CronTriggerImpl cronTriggerImpl)
        {
            var triggerInfo = new TriggerModel
            {
                name = cronTriggerImpl.Name,
                group = cronTriggerImpl.Group,
                calendarName = cronTriggerImpl.CalendarName,
                description = cronTriggerImpl.Description,
                startTime = cronTriggerImpl.StartTimeUtc.ToString(),
                endTime = cronTriggerImpl.EndTimeUtc != null ? ((DateTimeOffset)cronTriggerImpl.EndTimeUtc).ToString() : "",
                cronExpression = cronTriggerImpl.CronExpressionString,
                rule = cronTriggerImpl.CronExpressionString,
                triggerType = "CronTriggerImpl",
                previousFireTime = cronTriggerImpl.GetPreviousFireTimeUtc() != null ? cronTriggerImpl.GetPreviousFireTimeUtc().ToString() : "",
                nextFireTime = cronTriggerImpl.GetNextFireTimeUtc() != null ? cronTriggerImpl.GetNextFireTimeUtc().ToString() : ""
            };

            return triggerInfo;
        }

        private static string FormatDTO(DateTimeOffset? dto)
        {
            return dto.HasValue ? dto.Value.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss") : string.Empty;
        }

        public static JobTriggerModel CronTriggerImplToJobTriggerModel(CronTriggerImpl cronTriggerImpl)
        {
            var jobTriggerInfo = new JobTriggerModel
            {
                jobName = cronTriggerImpl.JobName,
                triggerGroup = cronTriggerImpl.Group,
                triggerName = cronTriggerImpl.Name,
                startTime = FormatDTO(cronTriggerImpl.StartTimeUtc),
                previousFireTime = FormatDTO(cronTriggerImpl.GetPreviousFireTimeUtc()),
                nextFireTime = FormatDTO(cronTriggerImpl.GetNextFireTimeUtc())
            };

            return jobTriggerInfo;
        }
    }

5.1.3 config文件

<configuration>
    <configSections>
        <section name="quartz" type="System.Configuration.NameValueSectionHandler" />
    </configSections>

 <quartz>
    <add key="quartz.scheduler.instanceName" value="QuartzTimedTaskScheduler" />
    <add key="quartz.scheduler.proxy" value="true" />
    <add key="quartz.threadPool.threadCount" value="5" />
    <add key="quartz.scheduler.proxy.address" value="tcp://127.0.0.1:556/QuartzTimedTaskScheduler" />
  </quartz>

5.2 WindowsServices 服务

 using Quartz;
 
 public class FireTimingTaskJob : IJob
    {
        public string TaskName { get; set; }

        #region IJob Members

        public void Execute(IJobExecutionContext context)
        {
 
            try
            {
                var content = string.Format("{0:yyyy-MM-dd HH:mm:ss.fff} Task:{1},Run Trigger:{2}", DateTime.Now, TaskName, context.Trigger.SerializeObject());
                Console.WriteLine(content);
            }
            catch
            {
                try
                {
                    System.Threading.Thread.Sleep(1000);
                   
                }
                catch (Exception ex)
                {
                    //log.ErrorFormat("Fire task-{0} by trigger-{1} failed. Exception:{2}", TaskName, context.Trigger.Key, ex);
                    var content = string.Format("{0:yyyy-MM-dd HH:mm:ss.fff} Task:{1},Run Exception:{2}", DateTime.Now, TaskName, ex);
                    Console.WriteLine(content);
                }
            }
        }

        #endregion
    }
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using QuartzTimedTaskJobs;必须要引用项目文件

namespace QuartzTimedTaskService
{
    public class QuartzHost
    {
        IScheduler sched;
        public void Start()
        {
            try
            {
                ISchedulerFactory sf = new StdSchedulerFactory();

                sched = sf.GetScheduler();
                sched.Start();
            }
            catch (Exception ex)
            {

                if (ex.InnerException != null)
                {
                    Console.WriteLine(ex.Message);
                    if (ex.InnerException.InnerException != null)
                    {
                        if (ex.InnerException.InnerException.InnerException != null)
                        {
                            Console.WriteLine(ex.InnerException.InnerException.InnerException.Message);
                        }
                        Console.WriteLine(ex.InnerException.InnerException.Message);
                    }
                    Console.WriteLine(ex.InnerException.Message);
                }
                Console.WriteLine(ex.Message);
            }

        }

        public void Stop()
        {
            if (sched != null)
            {
                sched.Shutdown(true);
                sched = null;
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;
using Topshelf.Extension;

namespace QuartzTimedTaskService
{
    class Program
    {
        static void Main(string[] args)
        {
            HostFactory.Run(x =>
            {
                x.Service<QuartzHost>(s =>
                {
                    s.ConstructUsing(name => new QuartzHost());
                    s.WhenStarted(h => h.Start());
                    s.WhenStopped(h => h.Stop());
                });

                x.SetDescription("Smt Quartz Timed Task Service.");
                x.SetDisplayName("Smt Quartz Timed Task Service");
                x.SetServiceName("SmtQuartzTimedTaskService");
                x.SetStartTimeout(TimeSpan.FromMinutes(2));
                x.SetStopTimeout(TimeSpan.FromMinutes(2));

                x.RunAsLocalSystem()
                 .StartAutomatically()
                 .EnableServiceRecovery(r =>
                 {
                     r.RestartService(1)
                      .RestartService(1)
                      .RestartService(1)
                      .SetResetPeriod(1);
                 })
                  .UseHostBuilder((environment, setting) => new CustomConsoleHostBuilder(environment, setting)); ;
            });
        }
    }
}
  <quartz>
    <add key="quartz.scheduler.instanceName" value="QuartzTimedTaskScheduler" />
    <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
    <add key="quartz.threadPool.threadCount" value="10" />
    <add key="quartz.threadPool.threadPriority" value="Normal" />
    <add key="quartz.jobStore.misfireThreshold" value="60000" />
    <add key="quartz.jobStore.tablePrefix" value="QRTZ_" />

    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.MySQLDelegate, Quartz" />
    <add key="quartz.jobStore.dataSource" value="QuartzTimedTask" />
    <add key="quartz.dataSource.QuartzTimedTask.connectionString" value="Server=192.168.1.100;Database=my_QuartzTimedTask;User=sa;Password=123456;Charset=utf8;Pooling=false;" />
    <add key="quartz.dataSource.QuartzTimedTask.provider" value="MySql-695" />

    <!--远程输出配置-->
    <add key="quartz.scheduler.exporter.type" value="Quartz.Simpl.RemotingSchedulerExporter, Quartz" />
    <add key="quartz.scheduler.exporter.port" value="556" />
    <add key="quartz.scheduler.exporter.bindName" value="QuartzTimedTaskScheduler" />
    <add key="quartz.scheduler.exporter.channelType" value="tcp" />
    <add key="quartz.scheduler.exporter.channelName" value="tcpQuartz" />
    <add key="quartz.scheduler.exporter.rejectRemoteRequests" value="false" />

  </quartz>

 

posted @ 2018-09-25 18:04  FH1004322  阅读(660)  评论(0编辑  收藏  举报