管理并发线程上的任务取消和完成



[ 这个问题需要重新构想。 我的一个线程队列必须在 STA 线程上运行,下面的代码无法适应这种情况。 特别是似乎 Task<> 选择了自己的线程,这对我不起作用。]

我有一个任务队列(BlockingCollection),我正在专用线程上运行。 该队列接收一系列 Task<> 对象,这些对象通过 while 循环在该线程中按顺序运行。

我需要一种方法来取消这一系列任务,以及一种知道任务都已完成的方法。 我一直无法弄清楚如何做到这一点。

这是我排队课的片段。 ProcessQueue 在与 main 不同的线程上运行。 队列作业调用发生在主线程上。

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实际上可能是"当所有工作都完成后,通知用户,然后做其他事情",所以它不必像上面那样严格地是同步函数调用,但我不知道如何实现这些。

(更复杂的是,我希望有几个交互的队列。 虽然我小心翼翼地保持并行化以防止死锁,但我不确定当取消被引入混合时会发生什么,但这可能超出了这个问题的范围。

WaitForCompletion() 听起来很简单。 创建信号量或事件,创建任务,其唯一操作是向信号灯发出信号,将任务排队,等待信号量。

当线程完成最后一个"真正的"任务时,信号量任务将运行,因此名为 WaitForCompletion 的线程将准备就绪/正在运行:)

类似的方法不适用于取消吗? 您创建/发出信号的优先级非常高的线程,该线程会耗尽所有待处理作业的队列,释放它们,排队信号量任务并等待"最后一个任务完成"信号?

最新更新