c# - 我如何等待 Quartz.Net 父作业中的子作业完成

标签 c# quartz.net

我有一个容器(父)作业。它包含子作业。 ParentJob 将在所有 childJobs 完成时完成。问题在代码中。

public class ParentJob : InterruptableJob
{
    private childrenAreCompleted = false;
    private ChildJobListener _listener;

    public override void Execute(IJobExecutionContext context)
    {
        var childs = new int[] { 1, 2, 3 };

        _listener = new ChildJobListener(childs.Length);
        _listener.OnCompleted += new Action(_listener_OnCompleted);

        JobKey jk = typeof(ChildJob).JobKey(); // My Type extension :)
        IMatcher<JobKey> matcher = KeyMatcher<JobKey>.KeyEquals(jk);// this is wrong because ParentJob could be called concurrently. 

        context.Scheduler.ListenerManager.AddJobListener(_listener, matcher);


        foreach (var child in childs)
        {
            JobDataMap jobData = new JobDataMap();
            jobData.Add("ParentId", context.FireInstanceId);//TODO: suspected I want to use this with listener for matching.But I could not find Matcher<JobDataMap>.

            context.Scheduler.TriggerJob(jk, jobData);
        }

        // Wait Till _listenerOnCompleted
        while (true)
        {
            Thread.Sleep(2000);
            if (childrenAreCompleted)
                break;
        }
    }

    void _listener_OnCompleted()
    {
       childrenAreCompleted=true;
    }
}

public class ChildJobListener : IJobListener
{
    private int _executedChildCount = 0;
    private int _totalChildCount = 0;

    public int ActiveChildCount
    {
        get
        {
            return _totalChildCount - _executedChildCount;
        }
    }

    public event Action OnCompleted;

    public ChildJobListener(int childCount)
    {
        _totalChildCount = childCount;
    }

    public void JobExecutionVetoed(IJobExecutionContext context)
    {
        throw new NotImplementedException();
    }

    public void JobToBeExecuted(IJobExecutionContext context)
    {
    }

    public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException)
    {
        _executedChildCount++;
        if (_totalChildCount == _executedChildCount)
        {
            if (OnCompleted != null)
                OnCompleted();
        }
    }

    public string Name
    {
        get { return "ChildJobListener"; }
    }
}

最佳答案

您可以通过将 IsLocking 标志传递给作业上下文来创建 synchronizedJob 的实现,具体取决于您的实现,您可能必须相应地设置父子作业。例如以下可能会给你方向

     public abstract class SynchronizedLoggedJob : IJob
    {
        private static readonly object _syncRoot = new object();

        protected abstract void JobExecute(IJobExecutionContext context);

        public void Execute(IJobExecutionContext context)
        {
            context.ThrowIfNull(nameof(context));
            if (Convert.ToBoolean(context.JobDetail.JobDataMap["IsLocking"]))
            {
                lock (_syncRoot)
                {
                    JobExecute(context);
                }
            }
            else
            {
                JobExecute(context);
            }
        }
}   




   <job>
      <name></name>
      <group></group>
      <description></description>
      <job-type></job-type>
      <!-- See, http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-03.html -->
      <durable>true</durable>
      <recover>false</recover>
      <job-data-map>
        <entry>
          <key>IsLocking</key>
          <value>True</value>
        </entry>
      </job-data-map>
    </job>

关于c# - 我如何等待 Quartz.Net 父作业中的子作业完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11779748/

相关文章:

c# - 获取正在 Windows 服务上运行的调度程序实例

c# - 根据字符格式化字符串

c# - 使用没有回发的按钮将旧设计更改为新设计

c# - 将代码放在依赖属性的 setter block 中是否安全,还是我应该始终使用回调方法?

c# - 将现有应用程序移植到 Microsoft Azure 面临哪些挑战?

c# - Azure - 多个辅助角色 - 无法存储作业 : Unable to store Job: 'job6' ,,因为已存在具有此标识的作业

quartz.net - 如何停止或暂停 Quartz 作业

c# - 使用 ScheduleJobs 调用计划

c# - 如何确保 WCF 服务不会与数据库并行通信

c# - quartz 调度器 : How to pass custom objects as JobParameter?