版本:Quartz 2.5 ,log4net 2.0.8
QuartzHelper
namespace Job.Common { public class QuartzHelper { private static List<IScheduler> _listsche = new List<IScheduler>(); /// <summary> /// 时间间隔执行任务 /// </summary> /// <typeparam name="T">任务类,必须实现IJob接口</typeparam> /// <param name="seconds">时间间隔(单位:毫秒)</param> public static void ExecuteInterval<T>(int seconds) where T : IJob { ISchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = factory.GetScheduler(); //IJobDetail job = JobBuilder.Create<T>().WithIdentity("job1", "group1").Build(); IJobDetail job = JobBuilder.Create<T>().Build(); ITrigger trigger = TriggerBuilder.Create() .StartNow() .WithSimpleSchedule(x => x.WithIntervalInSeconds(seconds).RepeatForever()) .Build(); _listsche.Add(scheduler); scheduler.ScheduleJob(job, trigger); scheduler.Start(); } /// <summary> /// 指定时间执行任务 /// </summary> /// <typeparam name="T">任务类,必须实现IJob接口</typeparam> /// <param name="cronExpression">cron表达式,即指定时间点的表达式</param> public static void ExecuteByCron<T>(string cronExpression) where T : IJob { ISchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = factory.GetScheduler(); IJobDetail job = JobBuilder.Create<T>().Build(); //DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddSeconds(1), 2); //DateTimeOffset endTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddYears(2), 3); ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create() // .StartAt(startTime).EndAt(endTime) .WithCronSchedule(cronExpression) .StartNow() .Build(); _listsche.Add(scheduler); scheduler.ScheduleJob(job, trigger); scheduler.Start(); //Thread.Sleep(TimeSpan.FromDays(2)); //scheduler.Shutdown(); } /// <summary> /// 每隔 seconds秒 ,重复执行times次 (如:times=-1重复执行;times=0只执行一次; /// </summary> /// <typeparam name="T"></typeparam> /// <param name="seconds"></param> /// <param name="times"></param> public static void ExecuteIntervalTime<T>(int seconds, int times) where T : IJob { ISchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = factory.GetScheduler(); //IJobDetail job = JobBuilder.Create<T>().WithIdentity("job1", "group1").Build(); IJobDetail job = JobBuilder.Create<T>().Build(); ITrigger trigger = TriggerBuilder.Create() .StartNow() .WithSimpleSchedule(x => x.WithIntervalInSeconds(seconds).WithRepeatCount(times)) .Build(); _listsche.Add(scheduler); scheduler.ScheduleJob(job, trigger); scheduler.Start(); } /// <summary> /// 关闭所有工厂调度任务 /// </summary> public static void ShutdownJobs() { try { if (_listsche.Count > 0) { foreach (var sched in _listsche) { if (!sched.IsShutdown) { logclass.Info(string.Format("关闭任务调度:{0}", sched.SchedulerName)); sched.Shutdown(); } } _listsche.Clear(); } } catch (Exception e) { logclass.Error(string.Format("关闭任务调度,出错:{0}", e), e); } } } public class QuartzManager<T> where T : class,IJob { #region 变量 private static ISchedulerFactory schedulerFactory = new StdSchedulerFactory(); //scheduler工厂 private static String JOB_GROUP_NAME = "JOBGROUP_NAME"; //Job群组名 private static String TRIGGER_GROUP_NAME = "TRIGGERGROUP_NAME"; //触发器群组名 #endregion #region 添加,删除,修改Job方法 /// <summary> /// 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 /// </summary> /// <param name="pStrJobName">任务名</param> /// <param name="pStrCronExpress">触发器表达式</param> public static void addJob(string pStrJobName, string pStrCronExpress, IDictionary<string, object> pDictionary) { try { IScheduler sched = schedulerFactory.GetScheduler(); // 创建任务 IJobDetail job = JobBuilder.Create<T>() .WithIdentity(pStrJobName, JOB_GROUP_NAME) .Build(); // 创建触发器 ITrigger trigger = TriggerBuilder.Create() .WithIdentity(pStrJobName, TRIGGER_GROUP_NAME) .WithCronSchedule(pStrCronExpress) .Build(); //给任务传参数 foreach (KeyValuePair<string, object> kvp in pDictionary) { job.JobDataMap.Put(kvp.Key, kvp.Value); } sched.ScheduleJob(job, trigger); } catch (Exception e) { throw new Exception(e.Message); } } /// <summary> /// 移除一个任务(使用默认的任务组名,触发器名,触发器组名) /// </summary> /// <param name="pStrJobName">任务名称</param> public static void RemoveJob(string pStrJobName) { try { IScheduler sched = schedulerFactory.GetScheduler(); JobKey jobKey = new JobKey(pStrJobName); TriggerKey triggerKey = new TriggerKey(pStrJobName, TRIGGER_GROUP_NAME); sched.PauseTrigger(triggerKey);// 停止触发器 sched.UnscheduleJob(triggerKey);// 移除触发器 sched.DeleteJob(jobKey);// 删除任务 } catch (Exception e) { throw new Exception(e.Message); } } /// <summary> /// 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) /// </summary> /// <param name="pStrJobName">任务名</param> /// <param name="pStrCronExpress">触发器表达式</param> public static void ModifyJobTime(string pStrJobName, string pStrCronExpress, IDictionary<string, object> pDictionary) { try { IScheduler sched = schedulerFactory.GetScheduler(); TriggerKey triggerKey = new TriggerKey(pStrJobName, TRIGGER_GROUP_NAME); ICronTrigger trigger = (ICronTrigger)sched.GetTrigger(triggerKey); if (trigger == null) { return; } RemoveJob(pStrJobName); addJob(pStrJobName, pStrCronExpress, pDictionary); } catch (Exception e) { throw new Exception(e.Message); } } #endregion #region 启动,关闭Job /// <summary> /// 启动所有定时任务 /// </summary> public static void startJobs() { try { IScheduler sched = schedulerFactory.GetScheduler(); sched.Start(); } catch (Exception e) { throw new Exception(e.Message); } } /// <summary> /// 关闭所有定时任务 /// </summary> public static void ShutdownJobs() { try { IScheduler sched = schedulerFactory.GetScheduler(); if (!sched.IsShutdown) { sched.Shutdown(); } } catch (Exception e) { throw new Exception(e.Message); } } #endregion } }
Loghelper
namespace Job.Common { /// <summary> /// 动态创建Logger工厂类 /// </summary> public static class LogHelper { private static readonly ConcurrentDictionary<string, ILog> loggerContainer = new ConcurrentDictionary<string, ILog>(); private static readonly Dictionary<string, ReadParamAppender> appenderContainer = new Dictionary<string, ReadParamAppender>(); private static object lockObj = new object(); //默认配置 private const int MAX_SIZE_ROLL_BACKUPS = 20; private const string LAYOUT_PATTERN = "%d [%t] %-5p %c - %m%n"; private const string DATE_PATTERN = "yyyyMMdd/HH".log""; private const string MAXIMUM_FILE_SIZE = "256MB"; private const string LEVEL = "debug"; //读取配置文件并缓存 static LogHelper() { IAppender[] appenders = LogManager.GetRepository().GetAppenders(); for (int i = 0; i < appenders.Length; i++) { if (appenders[i] is ReadParamAppender) { ReadParamAppender appender = (ReadParamAppender)appenders[i]; if (appender.MaxSizeRollBackups == 0) { appender.MaxSizeRollBackups = MAX_SIZE_ROLL_BACKUPS; } if (appender.Layout != null && appender.Layout is log4net.Layout.PatternLayout) { appender.LayoutPattern = ((log4net.Layout.PatternLayout)appender.Layout).ConversionPattern; } if (string.IsNullOrEmpty(appender.LayoutPattern)) { appender.LayoutPattern = LAYOUT_PATTERN; } if (string.IsNullOrEmpty(appender.DatePattern)) { appender.DatePattern = DATE_PATTERN; } if (string.IsNullOrEmpty(appender.MaximumFileSize)) { appender.MaximumFileSize = MAXIMUM_FILE_SIZE; } if (string.IsNullOrEmpty(appender.Level)) { appender.Level = LEVEL; } lock (lockObj) { appenderContainer[appenders[i].Name] = appender; } } } } /// <summary> /// 文本日志 /// </summary> /// <param name="loggerName"></param> /// <returns></returns> public static ILog GetCustomLogger(string loggerName, string category = null, bool additivity = false) { return loggerContainer.GetOrAdd(loggerName, delegate(string name) { RollingFileAppender newAppender = null; ReadParamAppender appender = null; if (appenderContainer.ContainsKey(loggerName)) { appender = appenderContainer[loggerName]; newAppender = GetNewFileApender(loggerName, string.IsNullOrEmpty(appender.File) ? GetFile(category, loggerName) : appender.File, appender.MaxSizeRollBackups, appender.AppendToFile, true, appender.MaximumFileSize, RollingFileAppender.RollingMode.Composite, appender.DatePattern, appender.LayoutPattern); } else { newAppender = GetNewFileApender(loggerName, GetFile(category, loggerName), MAX_SIZE_ROLL_BACKUPS, true, false, MAXIMUM_FILE_SIZE, RollingFileAppender.RollingMode.Date, DATE_PATTERN, LAYOUT_PATTERN); } log4net.Repository.Hierarchy.Hierarchy repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); Logger logger = repository.LoggerFactory.CreateLogger(repository, loggerName); logger.Hierarchy = repository; logger.Parent = repository.Root; logger.Level = GetLoggerLevel(appender == null ? LEVEL : appender.Level); logger.Additivity = additivity; logger.AddAppender(newAppender); logger.Repository.Configured = true; return new LogImpl(logger); }); } //如果没有指定文件路径则在运行路径下建立 Log{loggerName}.txt private static string GetFile(string category, string loggerName) { if (string.IsNullOrEmpty(category)) { return string.Format(@"Log{0}", loggerName); } else { return string.Format(@"Log{0}{1}", category, loggerName); } } private static Level GetLoggerLevel(string level) { if (!string.IsNullOrEmpty(level)) { switch (level.ToLower().Trim()) { case "debug": return Level.Debug; case "info": return Level.Info; case "warn": return Level.Warn; case "error": return Level.Error; case "fatal": return Level.Fatal; } } return Level.Debug; } private static RollingFileAppender GetNewFileApender(string appenderName, string file, int maxSizeRollBackups, bool appendToFile = true, bool staticLogFileName = false, string maximumFileSize = "50MB", RollingFileAppender.RollingMode rollingMode = RollingFileAppender.RollingMode.Date, string datePattern = "yyyyMMdd".log"", string layoutPattern = "%d [%t] %-5p %c - %m%n") { RollingFileAppender appender = new RollingFileAppender { LockingModel = new FileAppender.MinimalLock(), Name = appenderName, File = file, AppendToFile = appendToFile, MaxSizeRollBackups = maxSizeRollBackups, MaximumFileSize = maximumFileSize, StaticLogFileName = staticLogFileName, RollingStyle = rollingMode, DatePattern = datePattern, }; PatternLayout layout = new PatternLayout(layoutPattern); appender.Layout = layout; layout.ActivateOptions(); appender.ActivateOptions(); return appender; } } /// <summary> /// 自定义读取配置文件的Appender /// </summary> public class ReadParamAppender : log4net.Appender.AppenderSkeleton { private string _file; public string File { get { return this._file; } set { _file = value; } } private int _maxSizeRollBackups; public int MaxSizeRollBackups { get { return this._maxSizeRollBackups; } set { _maxSizeRollBackups = value; } } private bool _appendToFile = true; public bool AppendToFile { get { return this._appendToFile; } set { _appendToFile = value; } } private string _maximumFileSize; public string MaximumFileSize { get { return this._maximumFileSize; } set { _maximumFileSize = value; } } private string _layoutPattern; public string LayoutPattern { get { return this._layoutPattern; } set { _layoutPattern = value; } } private string _datePattern; public string DatePattern { get { return this._datePattern; } set { _datePattern = value; } } private string _level; public string Level { get { return this._level; } set { _level = value; } } protected override void Append(log4net.Core.LoggingEvent loggingEvent) { } } }
QuartzUtil
public static class QuartzUtil { private static ISchedulerFactory sf = null; private static IScheduler sched = null; static QuartzUtil() { sf = new StdSchedulerFactory(); sched = sf.GetScheduler(); sched.Start(); } /// <summary> /// 添加Job 并且以定点的形式运行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="CronTime"></param> /// <param name="jobDataMap"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, string CronTime, string jobData) where T : IJob { IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").UsingJobData("jobData", jobData).Build(); ICronTrigger CronTrigger = new CronTriggerImpl(JobName + "_CronTrigger", JobName + "_TriggerGroup", CronTime); return sched.ScheduleJob(jobCheck, CronTrigger); } /// <summary> /// 添加Job 并且以定点的形式运行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="CronTime"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, string CronTime) where T : IJob { return AddJob<T>(JobName, CronTime, null); } /// <summary> /// 添加Job 并且以周期的形式运行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="SimpleTime">毫秒数</param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, int SimpleTime) where T : IJob { return AddJob<T>(JobName, DateTime.UtcNow.AddMilliseconds(1), TimeSpan.FromMilliseconds(SimpleTime)); } /// <summary> /// 添加Job 并且以周期的形式运行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="SimpleTime">毫秒数</param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime) where T : IJob { return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime)); } /// <summary> /// 添加Job 并且以周期的形式运行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="SimpleTime"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime) where T : IJob { return AddJob<T>(JobName, StartTime, SimpleTime, new Dictionary<string, object>()); } /// <summary> /// 添加Job 并且以周期的形式运行 (kk /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="StartTime"></param> /// <param name="SimpleTime"></param> /// <param name="map"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime, Dictionary<string, object> map) where T : IJob { return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime), map); } /// <summary> /// 添加Job 并且以周期的形式运行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="StartTime"></param> /// <param name="SimpleTime">毫秒数</param> /// <param name="jobDataMap"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime, string MapKey, object MapValue) where T : IJob { Dictionary<string, object> map = new Dictionary<string, object>(); map.Add(MapKey, MapValue); return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime), map); } /// <summary> /// 添加Job 并且以周期的形式运行 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="JobName"></param> /// <param name="StartTime"></param> /// <param name="SimpleTime"></param> /// <param name="jobDataMap"></param> /// <returns></returns> public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime, Dictionary<string, object> map) where T : IJob { IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").Build(); jobCheck.JobDataMap.PutAll(map); ISimpleTrigger triggerCheck = new SimpleTriggerImpl(JobName + "_SimpleTrigger", JobName + "_TriggerGroup", StartTime, null, SimpleTriggerImpl.RepeatIndefinitely, SimpleTime); return sched.ScheduleJob(jobCheck, triggerCheck); } /// <summary> /// 修改触发器时间,需要job名,以及修改结果 /// CronTriggerImpl类型触发器 /// </summary> public static void UpdateTime(string jobName, string CronTime) { TriggerKey TKey = new TriggerKey(jobName + "_CronTrigger", jobName + "_TriggerGroup"); CronTriggerImpl cti = sched.GetTrigger(TKey) as CronTriggerImpl; cti.CronExpression = new CronExpression(CronTime); sched.RescheduleJob(TKey, cti); } /// <summary> /// 修改触发器时间,需要job名,以及修改结果 /// SimpleTriggerImpl类型触发器 /// </summary> /// <param name="jobName"></param> /// <param name="SimpleTime">分钟数</param> public static void UpdateTime(string jobName, int SimpleTime) { UpdateTime(jobName, TimeSpan.FromMinutes(SimpleTime)); } /// <summary> /// 修改触发器时间,需要job名,以及修改结果 /// SimpleTriggerImpl类型触发器 /// </summary> public static void UpdateTime(string jobName, TimeSpan SimpleTime) { TriggerKey TKey = new TriggerKey(jobName + "_SimpleTrigger", jobName + "_TriggerGroup"); SimpleTriggerImpl sti = sched.GetTrigger(TKey) as SimpleTriggerImpl; sti.RepeatInterval = SimpleTime; sched.RescheduleJob(TKey, sti); } /// <summary> /// 暂停所有Job /// 暂停功能Quartz提供有很多,以后可扩充 /// </summary> public static void PauseAll() { sched.PauseAll(); } /// <summary> /// 恢复所有Job /// 恢复功能Quartz提供有很多,以后可扩充 /// </summary> public static void ResumeAll() { sched.ResumeAll(); } /// <summary> /// 删除Job /// 删除功能Quartz提供有很多,以后可扩充 /// </summary> /// <param name="JobName"></param> public static void DeleteJob(string JobName) { JobKey jk = new JobKey(JobName, JobName + "_Group"); sched.DeleteJob(jk); } /// <summary> /// 卸载定时器 /// </summary> /// <param name="waitForJobsToComplete">是否等待job执行完成</param> public static void Shutdown(bool waitForJobsToComplete) { sched.Shutdown(waitForJobsToComplete); } }