How can I wait for the completion of work with children in the parent task in Quartz.Net

I have a Container (Parent). It contains children's assignments. ParentJob will be completed when all children are completed. Questions are in code.

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"; }
    }
}
+5
source share
1 answer

You can create your synchronizedJob implementation by passing the IsLocking flag to the context of your work, depending on your implementation, you may need to set up parent child tasks accordingly. for example, the following may give you direction

     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>
0
source

All Articles