Quartz.Net - 自定义基础 Job





5.00/5 (4投票s)
为 quartz 调度器开发创建自定义基础作业类
介绍
Quartz.Net 允许你调度任务来运行。这些任务通常使用来自 JobDataMap
对象中的变量进行配置。我想要一个简单有效的类,它允许我使用 .NET 属性,而不是在需要调度任务时依赖于配置和设置 JobDataMap
。
背景
一个重要的方面是我想要解决的是,虽然 Quartz.Net JobDataMap
类允许你存储对象,但我只想存储字符串值。问题是,如果你在 JobDataMap
中存储 .net 对象,你也会面临类型或版本问题的风险。
利用 Json.NET 框架,我构建了一个简单的 QuartzJobBase
类,它允许我只存储字符串值,但也允许我在 JobDataMap
中存储更复杂的对象。
使用代码
在开始之前,请确保你引用了 Json.NET 程序集。
QuartzJobBase 类是 Quartz.Net job 的抽象实现。它负责 3 个重要方面。
- 将当前属性值序列化到 JobDataMap
- 从 JobDataMap 反序列化属性值
- 用
JobExecutionException
包装实现抛出的异常。
要将属性值序列化到 JobDataMap 中,你可以简单地在你的对象上调用 BuildJobDataMap()
来构建一个包含你当前属性值的 JobDataMap
实例。
对象的反序列化由类自动处理,因为它在 Quartz 调度器执行任务时执行。
using System; using System.Linq; using System.Reflection; using Newtonsoft.Json; namespace Quartz.Custom { public abstract class QuartzJobBase : IJob { private static readonly Newtonsoft.Json.JsonSerializerSettings JsonSettings; static QuartzJobBase() { JsonSettings = new JsonSerializerSettings(); JsonSettings.TypeNameHandling = TypeNameHandling.Auto; JsonSettings.TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; } public void Execute(IJobExecutionContext context) { try { ReadFromJobDataMap(context.MergedJobDataMap); InternalExecute(context); } catch (Exception ex) { // Jobs should throw JobExecutionException if error occurred. // Wrap internal exceptions with JobExecutionException. JobExecutionException jex = new JobExecutionException(ex); throw jex; } } protected abstract void InternalExecute(IJobExecutionContext context); #region JobDataMap & Serialization public JobDataMap BuildJobDataMap() { JobDataMap data = new JobDataMap(); foreach (var prop in GetType().GetProperties()) { object value = prop.GetValue(this, null); string s = GetPropertyValue(prop); data.Add(prop.Name, s); } return data; } private void ReadFromJobDataMap(JobDataMap data) { PropertyInfo[] properties = GetType().GetProperties(); foreach (var key in data.Keys) { var p = properties.Where(x => x.Name == key).SingleOrDefault(); if (p != null) { SetPropertyValue(p, data.GetString(key)); } } } private string GetPropertyValue(PropertyInfo property) { object value = property.GetValue(this, null); return JsonConvert.SerializeObject(value, Formatting.None, JsonSettings); } private void SetPropertyValue(PropertyInfo property, string value) { object obj = JsonConvert.DeserializeObject(value, property.PropertyType, JsonSettings); property.SetValue(this, obj, null); } #endregion } }
一个示例 job 实现如下所示。
public class HelloWorldJob : QuartzJobBase { public string Name { get; set; } public int FavoriteNumber { get; set; } public List<string> CustomList { get; private set; } public HelloWorldJob() { CustomList = new List<string>(); } protected override void InternalExecute(Quartz.IJobExecutionContext context) { Console.WriteLine("Hello World from {0} ({1})", Name, FavoriteNumber); foreach (var item in CustomList) { Console.WriteLine("{0} CUSTOM LIST: {1}", Name, item); } } }
通过提供 JobDataMap 来调度任务
HelloWorldJob j = new HelloWorldJob(); j.Name = "My Name"; j.FavoriteNumber = r.Next(100); for (int x = 0; x < 10; x++) { j.CustomList.Add(r.Next().ToString()); } sched.ScheduleJob( JobBuilder.Create(typeof.HellowWorldJob) .UsingJobData(j.BuildJobDataMap()) .Build(), TriggerBuilder.Create() .StartNow() .Build());
尽情享用!