stevenjin 2024-10-14 16:27 采纳率: 98%
浏览 3
已结题

Quartz.NET怎样判断工作链中最后一个已经触发,再进入循环中的下一个工作链

Quartz.NET
1.如下是一个按顺序执行的单一工作链
2.问题:如果要重复该工作链多次(只是参数不同),怎样判断上一个触发已经结束呢?正确的方法是怎样呢?


 // Get scheduler and add object
 IScheduler scheduler = MySchedulerFactory.GetScheduler();
 JobKey firstJobKey = JobKey.Create("FirstJob", "Pipeline");
 JobKey secondJobKey = JobKey.Create("SecondJob", "Pipeline");
 JobKey thirdJobKey = JobKey.Create("ThirdJob", "Pipeline");

 // Create job and trigger
 IJobDetail firstJob = JobBuilder.Create<FeedingJob.OuterJob>()
 .WithIdentity(firstJobKey)
 .UsingJobData("outerSays", "Hello World,I'm outSide!")
 //.StoreDurably(true)
 .Build();

 IJobDetail secondJob = JobBuilder.Create<FeedingJob.InnnerJob1>()
 .WithIdentity(secondJobKey)
 .UsingJobData("innerSays", "Hello World,I'm inSide1!")
 .UsingJobData("executeNext", "false")
 .StoreDurably(true)//指示Quartz在Job成为“孤儿”时不要删除Job(当Job不再有Trigger引用它时),按顺序触发关键
 .Build();

 IJobDetail thirdJob = JobBuilder.Create<FeedingJob.InnnerJob1>()
 .WithIdentity(thirdJobKey)
 .UsingJobData("innerSays", "Hello World,I'm inSide2!")
 .UsingJobData("executeNext", "true")
 .StoreDurably(true)
 .Build();

 ITrigger firstJobTrigger = TriggerBuilder.Create()
 .WithIdentity("Trigger", "Pipeline")
 .WithSimpleSchedule(x => x
 .WithMisfireHandlingInstructionFireNow()
 .WithIntervalInSeconds(15)
 .WithRepeatCount(30000)).StartAt(DateBuilder.FutureDate(1, IntervalUnit.Second))
 .Build();

 JobChainingJobListener listener = new JobChainingJobListener("Pipeline Chain");
 listener.AddJobChainLink(firstJobKey, secondJobKey);
 listener.AddJobChainLink(secondJobKey, thirdJobKey);

 scheduler.ListenerManager.AddJobListener(listener, GroupMatcher<JobKey>.GroupEquals("Pipeline"));

 // Run it all in chain
 scheduler.Start();
 scheduler.ScheduleJob(firstJob, firstJobTrigger);
 scheduler.AddJob(secondJob, false, true);
 scheduler.AddJob(thirdJob, false, true);


 public class FeedingJob
 {
     //[DisallowConcurrentExecution]
     public class OuterJob : IJob
     {
         public Task Execute(IJobExecutionContext context)
         {
             JobKey jobKey = context.JobDetail.Key;
             JobDataMap dataMap = context.JobDetail.JobDataMap;
             string jobSays = dataMap.GetString("outerSays");
             Console.WriteLine($"Outer job executed[{jobKey}]:{DateTime.Now},Content:{jobSays}");
             Thread.Sleep(2000);
             return Task.CompletedTask;
         }
     }

     //[DisallowConcurrentExecution]
     public class InnnerJob1 : IJob
     {
         public Task Execute(IJobExecutionContext context)
         {
             JobKey jobKey = context.JobDetail.Key;
             JobDataMap dataMap = context.JobDetail.JobDataMap;
             string jobSays = dataMap.GetString("innerSays");
             string executeNext = dataMap.GetString("executeNext");
             Console.WriteLine($"Innner job executed[{jobKey}]:{DateTime.Now},Content:{jobSays},executeNext:{executeNext}");
             Thread.Sleep(2000);
             return Task.CompletedTask;
         } 
     }   
 }
  • 写回答

1条回答 默认 最新

  • 清水白石008 2024-10-14 17:10
    关注
    🕒下午好,题主!目前:🟢[在线]
    📢参考GPT-4o mini 模型、由清水白石008整理提供!
    📣今日金句:成功是百分之一的灵感,加上百分之九十九的汗水。”** — 托马斯·爱迪生
    

    Quartz.NET 提供了一个 JobChainingJobListener 类,可以用来实现工作链的执行。这个类可以监听一个工作链中的每个工作的完成事件,并在完成后触发下一个工作。

    要判断上一个工作已经结束,可以使用 JobChainingJobListenerJobWasExecuted 方法。这个方法会在每个工作完成后被调用,可以在这个方法中检查工作链的状态,并决定是否触发下一个工作。

    以下是一个示例代码,展示了如何使用 JobChainingJobListener 来实现工作链的执行:

    public class JobChainingJobListener : IJobListener
    {
        private readonly string _chainName;
        private readonly Dictionary<JobKey, JobKey> _jobChainLinks;
    
        public JobChainingJobListener(string chainName)
        {
            _chainName = chainName;
            _jobChainLinks = new Dictionary<JobKey, JobKey>();
        }
    
        public void AddJobChainLink(JobKey fromJobKey, JobKey toJobKey)
        {
            _jobChainLinks[fromJobKey] = toJobKey;
        }
    
        public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException)
        {
            JobKey jobKey = context.JobDetail.Key;
            if (_jobChainLinks.ContainsKey(jobKey))
            {
                JobKey nextJobKey = _jobChainLinks[jobKey];
                IJobDetail nextJob = context.Scheduler.GetJobDetail(nextJobKey);
                if (nextJob != null)
                {
                    context.Scheduler.TriggerJob(nextJobKey);
                }
            }
        }
    
        public void JobExecutionVetoed(IJobExecutionContext context)
        {
            // 不需要实现
        }
    
        public void JobToBeExecuted(IJobExecutionContext context)
        {
            // 不需要实现
        }
    }
    

    在这个示例代码中,JobChainingJobListener 类维护了一个工作链的状态,包括每个工作的下一个工作的键。 当一个工作完成后,JobWasExecuted 方法会被调用,检查工作链的状态,并决定是否触发下一个工作。

    要重复执行工作链,可以使用 Quartz.NET 的 Trigger 类来创建一个循环触发器。例如:

    ITrigger trigger = TriggerBuilder.Create()
        .WithIdentity("Trigger", "Pipeline")
        .WithSimpleSchedule(x => x
            .WithMisfireHandlingInstructionFireNow()
            .WithIntervalInSeconds(15)
            .WithRepeatCount(30000))
        .StartAt(DateBuilder.FutureDate(1, IntervalUnit.Second))
        .Build();
    

    这个触发器会每 15 秒执行一次,重复 30000 次。

    总之,使用 JobChainingJobListener 类和 Quartz.NET 的 Trigger 类,可以实现工作链的执行和重复执行。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月18日
  • 已采纳回答 10月18日
  • 修改了问题 10月14日
  • 创建了问题 10月14日

悬赏问题

  • ¥60 Matlab联合CRUISE仿真编译dll文件报错
  • ¥15 脱敏项目合作,ner需求合作
  • ¥15 脱敏项目合作,ner需求合作
  • ¥30 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId