.NET5项目移植后MassTransit集成Quartz调度触发ScheduledMessageJob无空构造函数错误
错误根因
适配.NET 5的MassTransit版本中,MassTransit.QuartzIntegration.ScheduledMessageJob需要依赖IBus实例投递触发后的定时消息,没有无参构造函数,你当前配置的Quartz默认JobFactory仅支持实例化带无参构造的Job,因此任务触发时实例化失败。同时你删除的旧版本SchedulerBusFactorySpecification对应的集成逻辑在新版本中没有补充配置,导致Quartz和MassTransit的调度关联中断。
修复步骤
1. 安装必要依赖(Windows服务端)
先安装对应版本的NuGet包:
MassTransit.Quartz:MassTransit与Quartz的集成包Quartz.Extensions.DependencyInjection:Quartz的.NET DI扩展包
2. 替换Windows服务端Quartz配置
删除你原有手动创建StdSchedulerFactory、手动启动Scheduler的代码,替换为如下DI注册逻辑:
services.AddQuartz(q => { // 关键配置:使用.NET DI容器创建Job实例,解决无参构造报错问题 q.UseMicrosoftDependencyInjectionJobFactory(); // 原有Quartz属性配置保持不变 q.SetProperty("quartz.scheduler.instanceName", "QuartzSchedulerInstance1"); q.SetProperty("quartz.scheduler.instanceId", "Quartz_instance_1"); q.SetProperty("quartz.threadPool.type", "Quartz.Simpl.SimpleThreadPool, Quartz"); q.SetProperty("quartz.threadPool.threadCount", "10"); q.SetProperty("quartz.threadPool.threadPriority", "2"); q.SetProperty("quartz.jobStore.misfireThreshold", "60000"); q.SetProperty("quartz.jobStore.type", "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"); q.SetProperty("quartz.jobStore.useProperties", "true"); q.SetProperty("quartz.jobStore.dataSource", "default"); q.SetProperty("quartz.jobStore.tablePrefix", "QRTZ_"); q.SetProperty("quartz.jobStore.lockHandler.type", "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz"); q.SetProperty("quartz.dataSource.default.connectionString", "Server=(local);Database=Quartz;Trusted_Connection=True;"); q.SetProperty("quartz.dataSource.default.provider", "SqlServer"); q.SetProperty("quartz.serializer.type", "json"); }); // 注册Quartz托管服务,自动管理Scheduler的启动、停止 services.AddQuartzHostedService(opt => { opt.WaitForJobsToComplete = true; });
3. 调整Windows服务端MassTransit配置
替换Quartz队列的原有配置,补充MassTransit与Quartz的集成逻辑:
cfg.ReceiveEndpoint(busSettings.QuartzQueueName, epc => { // 替换你原有手动注册ScheduleMessageConsumer、CancelScheduledMessageConsumer的代码 // 该方法等效于你旧版本注释的SchedulerBusFactorySpecification功能 epc.UseQuartzScheduler(context.GetRequiredService<ISchedulerFactory>(), epc.InputAddress); // 原有分区器配置保留 var partitioner = cfg.CreatePartitioner(16); epc.ConfigureConsumer<ScheduleMessageConsumer>(context, x => x.Message<ScheduleMessage>(m => m.UsePartitioner(partitioner, p => p.Message.CorrelationId))); epc.ConfigureConsumer<CancelScheduledMessageConsumer>(context, x => x.Message<CancelScheduledMessage>(m => m.UsePartitioner(partitioner, p => p.Message.TokenId))); epc.Durable = true; });
4. Web端配置调整
Web端仅负责发送调度请求,不承担任务触发逻辑,原有配置无需修改。
5. 验证操作
先清空Quartz数据库中已生成的旧任务数据,避免历史无效任务触发报错,再按顺序启动Windows服务、Web应用,发送定时消息验证即可。
内容的提问来源于stack exchange,提问作者Sylvain Gantois
相关产品推荐
相关产品推荐

