Quartz定时服务帮助类
using Quartz; using Quartz.Impl; using System; using System.Collections.Generic; namespace Fenla.Common { /// <summary> /// 定时任务调度帮助基类 /// 注意:job和trigger使用相同的jobName和jobGroup /// </summary> public static class QuartzHelper { private static ISchedulerFactory scheduleFactory = null; static QuartzHelper() { System.Collections.Specialized.NameValueCollection properties = new System.Collections.Specialized.NameValueCollection(); properties["quartz.scheduler.instanceName"] = "FenlaQuartz"; // set thread pool info properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz"; int threadCount = LoadDeputySet.GetInstance.Load().QuartzThreadCount; threadCount = threadCount > 0 ? threadCount : 20; properties["quartz.threadPool.threadCount"] = threadCount.ToString();//线程数 properties["quartz.threadPool.threadPriority"] = "Normal"; scheduleFactory = new StdSchedulerFactory(properties); } /// <summary> /// 添加CronTrigger类型的定时任务 /// </summary> /// <typeparam name="T">实现具体业务逻辑的类</typeparam> /// <param name="jobName">任务名称</param> /// <param name="jobGroup">任务所属分组</param> /// <param name="cronExpression">Cron时间表达式[秒 分 时 日 月 星期 年(可选)]</param> /// <param name="startRunTime">任务开始时间</param> /// <param name="endRunTime">任务结束时间</param> /// <param name="param">传递给任务类的参数</param> /// <returns></returns> public static bool AddCronTriggerJob(Type jobClassType, string jobName, string jobGroup, string cronExpression, DateTime? startRunTime, DateTime? endRunTime, Dictionary<string, object> param = null) { if (typeof(IJob).IsAssignableFrom(jobClassType) == false) { return false; }//任务类必须继承IJob接口 if (string.IsNullOrEmpty(cronExpression)) { return false; } try { if (startRunTime == null) { startRunTime = DateTime.Now; } DateTimeOffset starRunTimeTemp = DateBuilder.NextGivenSecondDate(startRunTime, 1);//开始时间 DateTimeOffset? endRunTimeTemp = null;//结束时间 if (endRunTime != null) { if (endRunTime.Value < startRunTime.Value) { return false; } endRunTimeTemp = DateBuilder.NextGivenSecondDate(endRunTime, 1); } //首先创建一个作业调度池 IScheduler schedule = scheduleFactory.GetScheduler(); //创建出来一个具体的作业 IJobDetail jobDetail = JobBuilder.Create(jobClassType).WithIdentity(jobName, jobGroup).Build(); if (param != null && param.Count > 0) { foreach (string key in param.Keys) { jobDetail.JobDataMap.Put(key, param[key]); } } //创建并配置一个触发器 ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create() .StartAt(starRunTimeTemp) .EndAt(endRunTimeTemp) .WithIdentity(jobName, jobGroup) .WithCronSchedule(cronExpression) .Build(); //加入作业调度池中 schedule.ScheduleJob(jobDetail, trigger); return true; } catch (Exception) { return false; } } /// <summary> /// 添加SimpleTrigger类型的定时任务 /// </summary> /// <typeparam name="T">实现具体业务逻辑的类</typeparam> /// <param name="jobName">任务名称</param> /// <param name="jobGroup">任务所属分组</param> /// <param name="repeatCount">重复次数</param> /// <param name="repeatIntervalSeconds">重复调用时间间隔</param> /// <param name="startRunTime">任务开始时间</param> /// <param name="endRunTime">任务结束时间</param> /// <param name="param">传递给任务类的参数[context.JobDetail.JobDataMap.GetString("key")获取]</param> /// <returns></returns> public static bool AddSimpleTriggerJob(Type jobClassType, string jobName, string jobGroup, int repeatCount, int repeatIntervalSeconds, DateTime? startRunTime, DateTime? endRunTime, Dictionary<string, object> param = null) { if (typeof(IJob).IsAssignableFrom(jobClassType) == false) { return false; }//任务类必须继承IJob接口 repeatIntervalSeconds = repeatIntervalSeconds <= 0 ? 1 : repeatIntervalSeconds; repeatCount = repeatCount < -1 ? -1 : repeatCount; try { if (startRunTime == null) { startRunTime = DateTime.Now; } DateTimeOffset starRunTimeTemp = DateBuilder.NextGivenSecondDate(startRunTime, 1);//开始时间 DateTimeOffset? endRunTimeTemp = null;//结束时间 if (endRunTime != null) { if (endRunTime.Value < startRunTime.Value) { return false; } endRunTimeTemp = DateBuilder.NextGivenSecondDate(endRunTime, 1); } //首先创建一个作业调度池 IScheduler schedule = scheduleFactory.GetScheduler(); //创建出来一个具体的作业 IJobDetail jobDetail = JobBuilder.Create(jobClassType).WithIdentity(jobName, jobGroup).Build(); if (param != null && param.Count > 0) { foreach (string key in param.Keys) { jobDetail.JobDataMap.Put(key, param[key]); } } //创建并配置一个触发器 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create() .StartAt(starRunTimeTemp) .EndAt(endRunTimeTemp) .WithIdentity(jobName, jobGroup) .WithSimpleSchedule(x => x.WithIntervalInSeconds(repeatIntervalSeconds).WithRepeatCount(repeatCount)) .Build(); //加入作业调度池中 schedule.ScheduleJob(jobDetail, trigger); return true; } catch (Exception) { return false; } } /// <summary> /// 修改CronTrigger任务的触发时间规则 /// </summary> /// <param name="jobName">任务名称</param> /// <param name="jobGroup">任务所属分组</param> /// <param name="cronExpression">Cron时间表达式[秒 分 时 日 月 星期 年(可选)]</param> /// <returns></returns> public static bool ModifyCronTriggerJobTime(string jobName, string jobGroup, string cronExpression) { try { IScheduler schedule = scheduleFactory.GetScheduler(); ICronTrigger trigger = (ICronTrigger)schedule.GetTrigger(new TriggerKey(jobName, jobGroup)); if (trigger == null) { return false; } string oldCron = trigger.CronExpressionString; if (oldCron != cronExpression) { schedule.PauseTrigger(new TriggerKey(jobName, jobGroup)); trigger.CronExpressionString = cronExpression; schedule.RescheduleJob(new TriggerKey(jobName, jobGroup), trigger); } return true; } catch (Exception) { return false; } } /// <summary> /// 修改SimpleTrigger任务的触发规则 /// </summary> /// <param name="jobName">任务名称</param> /// <param name="jobGroup">任务所属分组</param> /// <param name="repeatCount">重复次数</param> /// <param name="repeatIntervalSeconds">重复时间间隔</param> /// <returns></returns> public static bool ModifySimpleTriggerJobTime(string jobName, string jobGroup, int repeatCount, int repeatIntervalSeconds) { try { IScheduler schedule = scheduleFactory.GetScheduler(); ISimpleTrigger trigger = (ISimpleTrigger)schedule.GetTrigger(new TriggerKey(jobName, jobGroup)); if (trigger == null) { return false; } int oldRepeatCount = trigger.RepeatCount; int oldRepeatInterval = trigger.RepeatInterval.Seconds; bool reset = false; if (oldRepeatCount != repeatCount || oldRepeatInterval != repeatIntervalSeconds) { reset = true; } if (reset == true) { schedule.PauseTrigger(new TriggerKey(jobName, jobGroup)); trigger.RepeatCount = repeatCount; trigger.RepeatInterval = new TimeSpan(0, 0, repeatIntervalSeconds); schedule.RescheduleJob(new TriggerKey(jobName, jobGroup), trigger); } return true; } catch (Exception) { return false; } } /// <summary> /// 删除指定任务 /// </summary> /// <param name="jobName">任务名称</param> /// <param name="jobGroup">任务所属分组</param> /// <returns></returns> public static bool DeleteJob(string jobName, string jobGroup) { try { IScheduler schedule = scheduleFactory.GetScheduler(); schedule.PauseTrigger(new TriggerKey(jobName, jobGroup)); //停止触发器 schedule.UnscheduleJob(new TriggerKey(jobName, jobGroup)); //删除触发器 schedule.DeleteJob(new JobKey(jobName, jobGroup)); //删除任务 return true; } catch (Exception) { return false; } } /// <summary> /// 重启指定任务 /// </summary> /// <param name="jobName">任务名称</param> /// <param name="jobGroup">任务所属分组</param> /// <returns></returns> public static bool ResumeJob(string jobName, string jobGroup) { try { IScheduler schedule = scheduleFactory.GetScheduler(); schedule.ResumeJob(new JobKey(jobName, jobGroup)); schedule.ResumeTrigger(new TriggerKey(jobName, jobGroup)); return true; } catch (Exception) { return false; } } /// <summary> /// 暂停指定任务 /// </summary> /// <param name="jobName">任务名称</param> /// <param name="jobGroup">任务所属分组</param> /// <returns></returns> public static bool PauseJob(string jobName, string jobGroup) { try { IScheduler schedule = scheduleFactory.GetScheduler(); schedule.PauseTrigger(new TriggerKey(jobName, jobGroup)); schedule.PauseJob(new JobKey(jobName, jobGroup)); return true; } catch (Exception) { return false; } } /// <summary> /// 启动所有任务 /// </summary> /// <returns></returns> public static bool StartAllJob() { try { IScheduler schedule = scheduleFactory.GetScheduler(); schedule.Start(); return true; } catch (Exception) { return false; } } /// <summary> /// 关闭所有任务 /// </summary> /// <param name="waitForJobsToComplete">是否等待任务完毕后关闭</param> /// <returns>是否全部关闭成功</returns> public static bool ShutDownJobs(bool waitForJobsToComplete) { try { IScheduler schedule = scheduleFactory.GetScheduler(); if (!schedule.IsShutdown) { schedule.Shutdown(); } return true; } catch (Exception) { return false; } } /// <summary> /// 检测任务运行状态 /// 当状态为Normal、Blocked,表示任务正在运行 /// </summary> /// <param name="jobName">任务名称</param> /// <param name="jobGroup">任务所属分组</param> /// <returns></returns> public static TriggerState IsRun(string jobName, string jobGroup) { try { IScheduler schedule = scheduleFactory.GetScheduler(); if (schedule.IsStarted == false) { return TriggerState.None; } return schedule.GetTriggerState(new TriggerKey(jobName, jobGroup)); } catch (Exception) { } return TriggerState.None; } // 扩展注意点: // 1.一个trigger只能对应一个job,同一个job可以定义多个trigger(多个trigger 各自独立的执行调度) // 2.同一个jobGroup中多个job的name不能相同,若未设置jobGroup则所有未设置group的job为同一个分组 // 3.同一个triggerGroup中多个trigger的name不能相同 } }
using Fenla.Common; using Fenla.Core.DataModel; using Fenla.Core.Enum; using Quartz; using System; using System.Collections.Generic; using System.Linq; namespace Fenla.Service { /// <summary> /// 定时任务调用类 /// </summary> public static class QuartzManager { /// <summary> /// 添加CronTrigger定时任务计划 /// </summary> /// <param name="taskData">任务配置信息</param> /// <param name="returnMessage">返回提示信息</param> /// <returns>是否添加成功</returns> public static bool AddCronTriggerTaskAndRun(QuartzTask taskData, ref string returnMessage) { if (taskData == null) { return false; } if (string.IsNullOrEmpty(taskData.JobName)) { returnMessage = "任务名称不能为空!"; return false; } if (string.IsNullOrEmpty(taskData.JobClassName)) { returnMessage = "任务类名称不能为空!"; return false; } Type jobClassType = Type.GetType(taskData.JobClassName);//"测试1.SimpleJob" if (jobClassType == null) { returnMessage = "任务类名称有误!"; return false; } if (typeof(IJob).IsAssignableFrom(jobClassType) == false)//类必须继承IJob接口 { returnMessage = "任务类必须继承IJob接口!"; return false; } taskData.JobGroup = string.IsNullOrWhiteSpace(taskData.JobGroup) ? taskData.JobName : taskData.JobGroup; using (ObjectContext db = new ObjectContext()) { int id = db.QuartzTask.Where(q => q.JobName == taskData.JobName && q.JobGroup == taskData.JobGroup).Select(q => q.Id).FirstOrDefault(); if (id > 0) { returnMessage = "已经存在" + taskData.JobGroup + "组的" + taskData.JobName + "任务名称!"; return false; } taskData.SimpleTriggerRepeatCount = null;//区别一次性任务 taskData.SimpleTriggerRepeatSeconds = null; taskData.CreateTime = DateTime.Now; if (taskData.Enabled == true) { string cronExpression = !string.IsNullOrEmpty(taskData.CronSecond) ? taskData.CronSecond : "*"; cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronMinute) ? taskData.CronMinute : "*"); cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronHour) ? taskData.CronHour : "*"); cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronDay) ? taskData.CronDay : "*"); cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronMonth) ? taskData.CronMonth : "*"); cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronWeek) ? taskData.CronWeek : "?"); cronExpression += " " + taskData.CronYear ?? string.Empty; bool result = QuartzHelper.AddCronTriggerJob(jobClassType, taskData.JobName, taskData.JobGroup, cronExpression, taskData.StarRunTime, taskData.EndRunTime);//添加定时任务 if (result == true) { taskData.RunStatus = QuartzRunStatus.Working; } else { returnMessage = "任务运行失败,请检查配置信息是否正确"; return false; } } else { taskData.RunStatus = QuartzRunStatus.Wait; } db.QuartzTask.Add(taskData); db.SaveChanges(); } return true; } /// <summary> /// 添加SimpleTrigger定时任务计划(一次性任务) /// 一次性任务必须设置运行结束时间 /// </summary> /// <param name="taskData">任务配置信息</param> /// <param name="returnMessage">返回提示信息</param> /// <returns>是否添加成功</returns> public static bool AddSimpleTriggerTaskAndRun(QuartzTask taskData, ref string returnMessage) { if (taskData == null) { return false; } if (string.IsNullOrEmpty(taskData.JobName)) { returnMessage = "任务名称不能为空!"; return false; } if (string.IsNullOrEmpty(taskData.JobClassName)) { returnMessage = "任务类名称不能为空!"; return false; } Type jobClassType = Type.GetType(taskData.JobClassName);//"测试1.SimpleJob" if (jobClassType == null) { returnMessage = "任务类名称有误!"; return false; } if (typeof(IJob).IsAssignableFrom(jobClassType) == false)//类必须继承IJob接口 { returnMessage = "任务类必须继承IJob接口!"; return false; } if (taskData.EndRunTime == null) { returnMessage = "一次性任务必须设置运行结束时间!"; return false; } if (taskData.SimpleTriggerRepeatCount == null) { taskData.SimpleTriggerRepeatCount = 0;//默认执行一次 } if (taskData.SimpleTriggerRepeatSeconds == null) { taskData.SimpleTriggerRepeatSeconds = 1;//默认一秒执行一次 } taskData.JobGroup = string.IsNullOrWhiteSpace(taskData.JobGroup) ? taskData.JobName : taskData.JobGroup; using (ObjectContext db = new ObjectContext()) { int id = db.QuartzTask.Where(q => q.JobName == taskData.JobName && q.JobGroup == taskData.JobGroup).Select(q => q.Id).FirstOrDefault(); if (id > 0) { returnMessage = "已经存在" + taskData.JobGroup + "组的" + taskData.JobName + "任务名称!"; return false; } taskData.CreateTime = DateTime.Now; if (taskData.Enabled == true) { bool result = QuartzHelper.AddSimpleTriggerJob(jobClassType, taskData.JobName, taskData.JobGroup, taskData.SimpleTriggerRepeatCount.Value , taskData.SimpleTriggerRepeatSeconds.Value, taskData.StarRunTime, taskData.EndRunTime);//添加定时任务 if (result == true) { taskData.RunStatus = QuartzRunStatus.Working; } else { returnMessage = "任务运行失败,请检查配置信息是否正确"; return false; } } else { taskData.RunStatus = QuartzRunStatus.Wait; } db.QuartzTask.Add(taskData); db.SaveChanges(); } return true; } /// <summary> /// 运行所有配置的定时任务 /// </summary> public static void Run() { LinBasic.Log.LogHelper.GetInstance.LogWithTime("Quartz定时任务服务已启动"); using (ObjectContext db = new ObjectContext()) { List<QuartzTask> taskList = db.QuartzTask.Where(q => q.Enabled == true).ToList(); if (taskList != null && taskList.Count > 0) { foreach (QuartzTask taskData in taskList) { Type jobClassType = Type.GetType(taskData.JobClassName);//"测试1.MyJob" if (jobClassType == null) { taskData.Message = "任务类名称有误,格式为“类命名空间.类名称”"; taskData.RunStatus = QuartzRunStatus.Wait; taskData.ModifyTime = DateTime.Now; continue; } bool result = false; if (taskData.SimpleTriggerRepeatCount == null) { string cronExpression = !string.IsNullOrEmpty(taskData.CronSecond) ? taskData.CronSecond : "*"; cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronMinute) ? taskData.CronMinute : "*"); cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronHour) ? taskData.CronHour : "*"); cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronDay) ? taskData.CronDay : "*"); cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronMonth) ? taskData.CronMonth : "*"); cronExpression += " " + (!string.IsNullOrEmpty(taskData.CronWeek) ? taskData.CronWeek : "?"); cronExpression += " " + taskData.CronYear ?? string.Empty; result = QuartzHelper.AddCronTriggerJob(jobClassType, taskData.JobName, taskData.JobGroup, cronExpression, taskData.StarRunTime, taskData.EndRunTime); } else { if (taskData.SimpleTriggerRepeatSeconds == null) { taskData.SimpleTriggerRepeatSeconds = 1;//默认一秒执行一次 } if (taskData.EndRunTime == null) { taskData.Message = "一次性任务运行结束时间不能为空!"; taskData.RunStatus = QuartzRunStatus.Wait; taskData.Enabled = false; taskData.ModifyTime = DateTime.Now; continue; } else if (taskData.EndRunTime > DateTime.Now) { result = QuartzHelper.AddSimpleTriggerJob(jobClassType, taskData.JobName, taskData.JobGroup, taskData.SimpleTriggerRepeatCount.Value, taskData.SimpleTriggerRepeatSeconds.Value, taskData.StarRunTime, taskData.EndRunTime); } else { taskData.Message = "任务运行完毕!"; taskData.RunStatus = QuartzRunStatus.Wait; taskData.Enabled = false; taskData.ModifyTime = DateTime.Now; continue; } } if (result == true) { taskData.RunStatus = QuartzRunStatus.Working; taskData.Message = string.Empty; taskData.ModifyTime = DateTime.Now; } else { taskData.Message = "任务运行失败,请检查配置信息是否正确"; } } db.SaveChanges(); QuartzHelper.StartAllJob(); } } } } }
自动清除临时任务
namespace Fenla.Service.TimedTask { /// <summary> /// 清除一次性任务定时任务 /// </summary> [DisallowConcurrentExecutionAttribute]//不允许并发执行属性 public class ClearTempTask : IJob { public ClearTempTask() { } public void Execute(IJobExecutionContext context) { using (ObjectContext dbContext = new ObjectContext()) { //清除一个星期之前的一次性任务 List<QuartzTask> tempTaskList = dbContext.QuartzTask.Where(q => q.SimpleTriggerRepeatCount != null && DbFunctions.AddDays(q.CreateTime, 30) < SqlFunctions.GetDate()).ToList(); foreach (QuartzTask item in tempTaskList) { dbContext.QuartzTask.Remove(item); } dbContext.SaveChanges(); } } } }
实体类
using Fenla.Core.Enum; using System; namespace Fenla.Core.DataModel { /// <summary> /// Quartz定时任务列表 /// </summary> public class QuartzTask : BaseEntity { /// <summary> /// 任务名称 /// </summary> public string JobName { get; set; } /// <summary> /// 任务所属分组 /// </summary> public string JobGroup { get; set; } /// <summary> /// 包含具体任务的类名称,必须包含命名空间,并且继承IJob接口 /// 格式如Fenla.Service.MyJob /// </summary> public string JobClassName { get; set; } /// <summary> /// 任务描述 /// </summary> public string JobDescription { get; set; } /// <summary> /// 运行状态 /// </summary> public QuartzRunStatus RunStatus { get; set; } private bool _enabled = true; /// <summary> /// 是否启用 /// </summary> public bool Enabled { get { return _enabled; } set { _enabled = value; } } /// <summary> /// 开始运行时间 /// </summary> public DateTime? StarRunTime { get; set; } /// <summary> /// 运行结束时间 /// </summary> public DateTime? EndRunTime { get; set; } /// <summary> /// Cron表达式中秒部分[0-59](多个用,号隔开) /// </summary> public string CronSecond { get; set; } /// <summary> /// Cron表达式中分钟部分[0-59](多个用,号隔开) /// </summary> public string CronMinute { get; set; } /// <summary> /// Cron表达式中小时部分[0-23](多个用,号隔开) /// </summary> public string CronHour { get; set; } /// <summary> /// Cron表达式中日期部分[1-31](多个用,号隔开) /// </summary> public string CronDay { get; set; } /// <summary> /// Cron表达式中月份部分[1-12](多个用,号隔开) /// </summary> public string CronMonth { get; set; } /// <summary> /// Cron表达式中星期部分[1-7](多个用,号隔开) /// </summary> public string CronWeek { get; set; } /// <summary> /// Cron表达式中年部分[1970-2099](多个用,号隔开) /// </summary> public string CronYear { get; set; } /// <summary> /// 运行时返回提示信息 /// </summary> public string Message { get; set; } /// <summary> /// 重复执行次数,用于SimpleTrigger触发器(临时任务) /// 如果为0表示执行一次,-1表示不限制次数(直到过期),默认为0 /// </summary> public int? SimpleTriggerRepeatCount { get; set; } /// <summary> /// 重复执行时间间隔,用于SimpleTrigger触发器(临时任务),默认为1 /// </summary> public int? SimpleTriggerRepeatSeconds { get; set; } } } namespace Fenla.Core.Enum { /// <summary> /// 定时任务调用枚举 /// </summary> public enum QuartzRunStatus { /// <summary> /// 未运行 /// </summary> Wait=0, /// <summary> /// 运行中 /// </summary> Working=10, /// <summary> /// 暂停 /// </summary> Pause=20 } } public class QuartzTaskMap : EntityTypeConfiguration<QuartzTask> { public QuartzTaskMap() { this.HasKey(c => c.Id); this.Property(c => c.JobName).IsRequired().HasMaxLength(50); this.Property(c => c.JobGroup).IsRequired().HasMaxLength(50); this.Property(c => c.JobClassName).IsRequired().HasMaxLength(200); this.Property(c => c.JobDescription).HasMaxLength(500); this.Property(c => c.RunStatus).IsRequired(); this.Property(c => c.Enabled).IsRequired(); this.Property(c => c.CronSecond).HasMaxLength(50); this.Property(c => c.CronMinute).HasMaxLength(50); this.Property(c => c.CronHour).HasMaxLength(50); this.Property(c => c.CronDay).HasMaxLength(50); this.Property(c => c.CronMonth).HasMaxLength(50); this.Property(c => c.CronWeek).HasMaxLength(50); this.Property(c => c.CronYear).HasMaxLength(50); this.Property(c => c.Message).HasMaxLength(500); this.Property(c => c.SimpleTriggerRepeatCount).IsOptional(); this.Property(c => c.SimpleTriggerRepeatSeconds).IsOptional(); } }
参数详解
http://blog.csdn.net/lzj0470/article/details/17786847
http://www.cnblogs.com/jys509/p/4628926.html#!comments
http://www.cnblogs.com/knowledgesea/p/4930469.html
iis回收冲突解决
在IIS中找到这个站点所用的程序池,点击“高级设置...”
在打开的列表中更改以下设置:
回收——固定时间间隔(分钟) 改为 0
——虚拟/专用内存限制(KB) 改为 0
进程模型——闲置超时(分钟) 改为 0
http://blog.csdn.net/rryqsh/article/details/8156558