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

问题描述 投票:5回答:1

我有一个容器(父)工作。它包含儿童工作。完成所有childJobs后,将完成ParentJob。问题在代码中。

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"; }
    }
}
c# quartz.net
1个回答
0
投票

您可以根据实现将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>
© www.soinside.com 2019 - 2024. All rights reserved.