如何在.NET 7的Quartz中实现两个任务的链式执行?
在.NET 7中实现Quartz任务链式执行
要让workerSecond在workerFirst执行完成后启动,你可以采用以下两种实用方案:
方案一:使用Quartz内置的JobChainingJobListener
这是Quartz官方提供的任务链式执行方案,无需修改任务类代码,仅通过配置就能实现一个任务完成后自动触发下一个任务,适合无额外判断逻辑的链式场景。
修改你的Program.cs代码如下:
services.AddQuartz(q => { q.UseMicrosoftDependencyInjectionJobFactory(); // 定义任务标识 var workerFirstKey = new JobKey("workerFirst"); q.AddJob<WorkerFirst>(options => options.WithIdentity(workerFirstKey)); var workerSecondKey = new JobKey("workerSecond"); q.AddJob<WorkerSecond>(options => options.WithIdentity(workerSecondKey)); // 配置workerFirst的每日触发器 q.AddTrigger(options => options .StartNow() .WithSimpleSchedule(x => x .WithIntervalInHours(24) .RepeatForever()) .ForJob(workerFirstKey) .WithIdentity("workerFirst-trigger")); // 添加链式监听器:workerFirst执行完成后触发workerSecond var chainListener = new JobChainingJobListener("jobChainListener"); chainListener.AddJobChainLink(workerFirstKey, workerSecondKey); q.AddJobListener(chainListener); }); services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
注:修正了你原代码中的两处笔误:
workerFaceit应为workerFirst,workerSecond变量末尾的冗余空格已移除,避免任务标识混乱。
方案二:在WorkerFirst中手动调度WorkerSecond
如果需要根据workerFirst的执行结果决定是否触发workerSecond(比如执行成功才触发,失败则跳过),可以在任务内部手动调度后续任务。
首先,在WorkerFirst中注入IScheduler用于调度任务:
public class WorkerFirst : IJob { private readonly IScheduler _scheduler; public WorkerFirst(IScheduler scheduler) { _scheduler = scheduler; } public async Task Execute(IJobExecutionContext context) { // 执行workerFirst的业务逻辑 Console.WriteLine("WorkerFirst执行完成"); // 可添加结果判断逻辑,比如仅在成功时触发 bool shouldTriggerSecond = true; if (shouldTriggerSecond) { // 手动调度workerSecond立即执行 var trigger = TriggerBuilder.Create() .StartNow() .WithIdentity($"workerSecond-trigger-{Guid.NewGuid()}") // 用唯一标识避免触发器冲突 .Build(); await _scheduler.TriggerJob(workerSecondKey, trigger); } } }
然后修改Program.cs,仅保留workerFirst的触发器(无需单独配置workerSecond的定时触发器):
services.AddQuartz(q => { q.UseMicrosoftDependencyInjectionJobFactory(); var workerFirstKey = new JobKey("workerFirst"); q.AddJob<WorkerFirst>(options => options.WithIdentity(workerFirstKey)); var workerSecondKey = new JobKey("workerSecond"); q.AddJob<WorkerSecond>(options => options.WithIdentity(workerSecondKey)); // 只配置workerFirst的每日触发器 q.AddTrigger(options => options .StartNow() .WithSimpleSchedule(x => x .WithIntervalInHours(24) .RepeatForever()) .ForJob(workerFirstKey) .WithIdentity("workerFirst-trigger")); }); services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
这种方式灵活性更高,能根据业务逻辑动态控制后续任务的触发。
内容的提问来源于stack exchange,提问作者michasaucer
相关产品推荐
相关产品推荐

