我有一个容器(父)作业。它包含子作业。 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/