我有一个容器(父)工作。它包含儿童工作。完成所有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"; }
}
}
答案 0 :(得分:0)
您可以通过根据实现将IsLocking标志传递到作业上下文中来创建syncedJob的实现,您可能必须相应地设置父子作业。例如,以下可能会为您指明方向
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>