假设我有两个主题。在一个帖子中,我正在执行一系列工作。在另一个线程上,我正在等待用户输入来控制这些作业(即,跳到下一个作业)。例如(伪C#):
public class Worker {
public List<Job> Jobs { get; set; }
public Worker(Controller anotherThread) {
anotherThread.SkipJobRequested += OnSkipJobRequested;
}
public DoWork() {
foreach (Job job in Jobs) {
// Do various work...
}
}
// Event that fires on Controller thread
public void OnSkipJobRequsted(Object sender, EventArgs args) {
// Somehow skip to the next job
}
}
我不确定我应该如何处理跳到下一份工作。我遇到的一种可能性是在请求跳过时设置一个实例变量(如IsSkipRequested
),并在DoWork()
内的各个接合点进行检查。
是否存在可用于处理此事件的其他模式?
答案 0 :(得分:3)
另一种模式是.Net类BackgroundWorker,它似乎应该适合您的目的。您可以将 Job 作为 BackgroundWorker 的子类,然后循环显示。区别在于 BackgroundWorker 不了解您的UI线程,只知道是否已请求取消。
在此模式中,UI线程将调用 CancelAsync ,然后您的 DoWork 方法将以方便的时间间隔检查 CancellationPending 以决定是否继续。您可以为 RunWorkerCompleted 事件处理程序中的下一个作业调用 RunWorkerAsync 。
答案 1 :(得分:1)
如果您将List<Jobs>
Queue<Jobs>
作为 _currentJob = Jobs.DeQueue();
Task.Factory.StartNew(() => {_currentJob.execute();},
() =>
{
//On task completion logic
ExecuteNextJobFromQueue();
}
,而不是DoWork执行foreach维护您对象中当前正在执行的作业,那么另一个建议就是(并且您已经提到了上述内容),您可以简单地出列每个项目准备好处理时。
任务并行库允许您指定取消令牌(尽管您可能必须将其传递给作业执行代码,并在那里处理取消),您可以在按下跳过时调用RequestCancellation,并启动队列中的下一个工作。此外,在启动新任务时,您可以指定要在完成时执行的操作,这将允许您将任务链接到一个顺序,并在需要时跳过任务。以下是没有取消令牌的示例:
{{1}}
请注意,如果Job执行多个任务而不是一个大的阻塞任务,这种方法可能会更有效,因为您需要在作业执行期间检查取消。