提示 对于新项目,推荐使用 JSON 作为数据库中存储数据的持久化格式。同时,强烈建议将 useProperties 设置为 true 以限制键值仅为字符串类型。

Quartz.Serialization.Json 提供了使用 Json.NET 处理实际序列化过程的作业存储 JSON 序列化支持。

安装

需要在使用 Quartz 的项目中添加 NuGet 包引用。

Install-Package Quartz.Serialization.Json
Shell

配置

经典属性配置方式

var properties = new NameValueCollection { ["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz", // "json" 是 "Quartz.Simpl.JsonObjectSerializer, Quartz.Serialization.Json" 的别名 ["quartz.serializer.type"] = "json" }; ISchedulerFactory schedulerFactory = new StdSchedulerFactory(properties);
C#

使用调度器构建器配置

var config = SchedulerBuilder.Create(); config.UsePersistentStore(store => { // 通常建议坚持使用字符串类型的属性键和值进行序列化 store.UseProperties = true; store.UseGenericDatabase(dbProvider, db => db.ConnectionString = "我的连接字符串"); store.UseJsonSerializer(); }); ISchedulerFactory schedulerFactory = config.Build();
C#

从二进制序列化迁移到 JSON

虽然没有官方的迁移解决方案,因为每个设置都可能有其特殊性,但存在一个可能适用于您的迁移方案。

  • 配置如下面的 MigratorSerializer 这样的自定义序列化器,它能读取二进制序列化格式并以 JSON 格式写入。
  • 让系统在运行过程中逐渐迁移,或者创建一个程序加载并把所有相关的序列化资产写回到数据库中。

示例混合序列化器

public class MigratorSerializer : IObjectSerializer { private BinaryObjectSerializer binarySerializer; private JsonObjectSerializer jsonSerializer; public MigratorSerializer() { this.binarySerializer = new BinaryObjectSerializer(); // you might need custom configuration, see sections about customizing // in documentation this.jsonSerializer = new JsonObjectSerializer(); } public T DeSerialize<T>(byte[] data) where T : class { try { // Attempt to deserialize data as JSON var result = this.jsonSerializer.DeSerialize<T>(data); return result; } catch (JsonReaderException) { // Presumably, the data was not JSON, we instead use the binary serializer return this.binarySerializer.DeSerialize<T>(data); } } public void Initialize() { this.binarySerializer.Initialize(); this.jsonSerializer.Initialize(); } public byte[] Serialize<T>(T obj) where T : class { return this.jsonSerializer.Serialize<T>(obj); } }
C#

自定义 JSON.NET

如果您需要自定义 JSON.NET 设置,需要继承自定义实现并覆盖 CreateSerializerSettings 方法。

class CustomJsonSerializer : JsonObjectSerializer { protected override JsonSerializerSettings CreateSerializerSettings() { var settings = base.CreateSerializerSettings(); settings.Converters.Add(new MyCustomConverter()); return settings; } }
C#

然后配置使用

store.UseSerializer<CustomJsonSerializer>(); // 或者配置为 "quartz.serializer.type" = "MyProject.CustomJsonSerializer, MyProject"
C#

自定义日历序列化

如果您实现了自定义日历,需要为其实现 ICalendarSerializer。有一个便利的基类 CalendarSerializer 可以帮助您获得强类型体验。

自定义日历及序列化器

[Serializable] class CustomCalendar : BaseCalendar { public CustomCalendar(){} protected CustomCalendar(SerializationInfo info, StreamingContext context) : base(info, context) { SomeCustomProperty = info?.GetBoolean("SomeCustomProperty") ?? true; } public bool SomeCustomProperty { get; set; } = true; public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info?.AddValue("SomeCustomProperty", SomeCustomProperty); } // JSON 序列化支持 class CustomCalendarSerializer : CalendarSerializer<CustomCalendar> { protected override CustomCalendar Create(JObject source) { return new CustomCalendar(); } protected override void SerializeFields(JsonWriter writer, CustomCalendar calendar) { writer.WritePropertyName("SomeCustomProperty"); writer.WriteValue(calendar.SomeCustomProperty); } protected override void DeserializeFields(CustomCalendar calendar, JObject source) { calendar.SomeCustomProperty = source["SomeCustomProperty"]!.Value<bool>(); } } }
C#

配置自定义日历序列化器

var config = SchedulerBuilder.Create(); config.UsePersistentStore(store => { store.UseJsonSerializer(json => json.AddCalendarSerializer<CustomCalendar>(new CustomCalendarSerializer())); }); // 或全局配置,上述代码实质上也是调用了 JsonObjectSerializer.AddCalendarSerializer<CustomCalendar>(new CustomCalendarSerializer());
C#