[这个问题需要重新构想。我的线程队列之一必须在STA线程上运行,并且下面的代码无法容纳该线程。特别是Task <>似乎选择了自己的线程,而这对我来说是行不通的。 ]
我有一个正在专用线程上运行的任务队列(BlockingCollection)。该队列接收一系列Task <>对象,它通过while循环在该线程内顺序运行。
我需要一种取消一系列任务的方法,并且需要一种知道所有任务都已完成的方法。我无法弄清楚该怎么做。
这是我的排队课程的一部分。 ProcessQueue在与main不同的线程上运行。 QueueJob调用发生在主线程上。
using Job = Tuple<Task<bool>, string>;
public class JobProcessor
{
private readonly BlockingCollection<Job> m_queue = new BlockingCollection<Job>();
volatile bool cancel_queue = false;
private bool ProcessQueue()
{
while (true)
{
if (m_queue.IsAddingCompleted)
break;
Job tuple;
if (!m_queue.TryTake(out tuple, Timeout.Infinite))
break;
var task = tuple.Item1;
var taskName = tuple.Item2;
try
{
Console.WriteLine("Task {0}::{1} starting", this.name, taskName);
task.RunSynchronously();
Console.WriteLine("Task {0}::{1} completed", this.name, taskName);
}
catch (Exception e)
{
string message = e.Message;
}
if (cancel_queue) // CANCEL BY ERASING TASKS AND NOT RUNNING.
{
while (m_queue.TryTake(out tuple))
{
}
}
} // while(true)
return true;
}
public Task<bool> QueueJob(Func<bool> input)
{
var task = new Task<bool>(input);
try
{
m_queue.Add(Tuple.Create(task, input.Method.Name));
}
catch (InvalidOperationException)
{
Task<bool> dummy = new Task<bool>(() => false);
dummy.Start();
return dummy;
}
return task;
}
以下是困扰我的功能:
public void ClearQueue()
{
cancel_queue = true;
// wait for queue to become empty. HOW?
cancel_queue = false;
}
public void WaitForCompletion()
{
// wait for all tasks to be completed.
// not sufficient to wait for empty queue because the last task
// must also execute and finish. HOW?
}
}
这里是一些用法:
class SomeClass
{
void Test()
{
JobProcessor jp = new JobProcessor();
// launch Processor loop on separate thread... code not shown.
// send a bunch of jobs via QueueJob... code not show.
// launch dialog... code not shown.
if (dialog_result == Result.Cancel)
jp.ClearQueue();
if (dialog_result == Result.Proceed)
jp.WaitForCompletion();
}
}
想法是在工作完成或取消之后,可能会发布新工作。通常,新的工作可能会异步进行。实际上,WaitForCompletion可能是“当所有工作完成后,通知用户然后再做其他事情”,因此,严格来说,它不一定像上面那样是一个同步函数调用,但是我不知道如何实现这些功能。
(更复杂的是,我希望有多个交互的队列。尽管我谨慎地将事物并行化以防止死锁,但是我不确定将取消引入到混合中会发生什么,但这很可能超出此问题的范围。)
答案 0 :(得分:0)
WaitForCompletion()听起来很容易。创建一个信号灯或事件,创建一个任务,该任务的唯一动作是发出信号灯,将任务排队,等待信号灯。
当线程完成最后一个“真实”任务时,将运行信号量任务,因此名为WaitForCompletion的线程将准备就绪/正在运行:)
类似的取消方法行不通吗?您创建/发出一个具有很高优先级的线程,以耗尽所有待处理作业的队列,处理它们,排队信号量任务并等待“最后一个任务完成”信号?