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

按顺序执行的Job中,分别用触发器并指定StartAt时,没有按预期工作

在下述按顺序执行的Job中,分别用触发器并指定StartAt可以?但没有按预期工作,正确方法是怎样呢?


private void FeedingOrderedPlanSchedule3()
{
    // 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("jobSays1", "Hello World1!")
    //.StoreDurably(true)
    .Build();

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

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

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

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

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

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

}
  • 写回答

1条回答 默认 最新

  • 月下独码 Java领域新星创作者 2024-10-14 10:39
    关注

    本答案参考 多次询问 ChatGPT-3.5 后选择的最佳回答,若是满意,还请采纳,谢谢

    1. 问题分析
      • 在Quartz.NET中,当使用JobChainingJobListener来按顺序执行作业(Job)时,指定触发器(Trigger)的StartAt时间没有按预期工作。这里涉及到作业调度、触发器的时间设置以及作业链的配置等多个方面的交互。
      • 可能的原因包括对JobChainingJobListener的工作机制理解不准确,或者是StartAt时间与作业链的顺序执行逻辑之间存在冲突。
    2. 关于JobChainingJobListener的理解
      • JobChainingJobListener的作用是定义作业之间的顺序关系。在这个例子中,listener.AddJobChainLink(firstJobKey, secondJobKey);表示firstJob执行完成后secondJob才会执行。
      • 然而,触发器的StartAt时间设置可能会干扰这个顺序。例如,如果firstJob的触发器firstJobTriggerStartAt时间设置得比secondJob的触发器secondJobTriggerStartAt时间晚,可能会导致顺序执行出现问题。
    3. 正确的方法
      • 调整StartAt时间逻辑
        • 确保firstJobStartAt时间早于secondJobStartAt时间,以符合作业链的顺序。例如,如果firstJobTriggerStartAtDateBuilder.FutureDate(1, IntervalUnit.Second),那么secondJobTriggerStartAt应该是一个大于1秒后的未来时间,如DateBuilder.FutureDate(2, IntervalUnit.Second)(假设firstJob执行时间很短)。
      • 检查作业存储和持久化设置
        • 在创建secondJob时,有.StoreDurably(true)的设置,这是为了在作业成为“孤儿”时不被删除。确保这个设置不会影响作业链的顺序执行。如果在作业调度过程中存在作业存储和恢复的情况,需要正确处理作业的持久化状态。
      • 验证作业和触发器的关联
        • 在调度作业时,要确保作业和触发器正确关联。例如,scheduler.ScheduleJob(firstJob, firstJobTrigger);scheduler.AddJob(secondJob, false, true);这两个操作。对于secondJob,虽然没有直接关联触发器的调度操作,但要确保它在firstJob执行完成后能正确获取到自己的触发器并执行。
      • 检查作业执行时间和重复次数
        • 对于firstJobsecondJobWithRepeatCount设置,要考虑作业的执行时间和重复次数是否会影响作业链的顺序。如果firstJob的重复执行时间过长,可能会延迟secondJob的开始时间,即使StartAt时间设置正确。例如,如果firstJobWithRepeatCount设置为一个很大的值,并且每次执行时间较长,那么secondJob可能无法按照预期的StartAt时间开始执行。

    以下是修改后的代码示例:

    private void FeedingOrderedPlanSchedule3()
    {
        // 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("jobSays1", "Hello World1!")
        //.StoreDurably(true)
       .Build();
    
        ITrigger firstJobTrigger = TriggerBuilder.Create()
       .WithIdentity("Trigger", "Pipeline")
       .WithSimpleSchedule(x => x
       .WithMisfireHandlingInstructionFireNow()
       .WithIntervalInSeconds(1)
       .WithRepeatCount(1)).StartAt(DateBuilder.FutureDate(1, IntervalUnit.Second))
       .Build();
    
        IJobDetail secondJob = JobBuilder.Create<FeedingJob.InnnerJob1>()
       .WithIdentity(secondJobKey)
       .UsingJobData("jobSays2", "Hello World2!")
       .StoreDurably(true)//指示Quartz在Job成为“孤儿”时不要删除Job(当Job不再有Trigger引用它时),按顺序触发关键
       .Build();
    
        ITrigger secondJobTrigger = TriggerBuilder.Create()
       .WithIdentity("Trigger", "Pipeline")
       .WithSimpleSchedule(x => x
       .WithMisfireHandlingInstructionFireNow()
       .WithIntervalInSeconds(1)
       .WithRepeatCount(3)).StartAt(DateBuilder.FutureDate(3, IntervalUnit.Second))
       .Build();
    
        JobChainingJobListener listener = new JobChainingJobListener("Pipeline Chain");
        listener.AddJobChainLink(firstJobKey, secondJobKey);
    
        scheduler.ListenerManager.AddJobListener(listener, GroupMatcher<JobKey>.GroupEquals("Pipeline"));
    
        // 调整作业和触发器的关联顺序,确保先添加firstJob和其触发器
        scheduler.Start();
        scheduler.ScheduleJob(firstJob, firstJobTrigger);
        scheduler.ScheduleJob(secondJob, secondJobTrigger);
        // 不需要再单独添加job,因为已经通过ScheduleJob关联了job和触发器
        //scheduler.AddJob(secondJob, false, true);
    }
    

    在这个修改后的代码中,调整了作业和触发器的关联顺序,并且确保secondJob也通过ScheduleJob来关联触发器,同时调整了StartAt时间以符合作业链的顺序逻辑。

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

报告相同问题?

问题事件

  • 系统已结题 10月22日
  • 已采纳回答 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