我有一个多线程环境,需要同步调用特殊任务(一个接一个)。
我创建了一个名为SynchronizedWorker
的简单静态类,其中包含Queue
个委托和锁。它包含一个ProcessTask
方法,该方法将新任务放入队列并等待任务完成。
它还包含ProcessTasks
私有方法,用于处理单独线程上的所有任务。如果在新任务到达时它正在运行,那么任务就会被置于队列中,我们会等待。
要通知调用者他的特定任务已完成,将为该任务创建一个ManualResetEvent
实例。但是,我不确定这是否是一个“好”的解决方案,因为可能有许多这样的任务排队等待,也许一个锁就足够了:
public static class SynchronizedWorker
{
private static Queue<KeyValuePair<Action, ManualResetEvent>> tasks = new Queue<KeyValuePair<Action, ManualResetEvent>>();
private static bool isProcessingTasks = false;
private static object syncRoot = new object();
public static void ProcessTask(Action task)
{
ManualResetEvent waitHandle = new ManualResetEvent(false);
bool startProcessing;
lock (syncRoot)
{
tasks.Enqueue(new KeyValuePair<Action, ManualResetEvent>(task, waitHandle));
// check if task processing need to start over
startProcessing = (isProcessingTasks == false);
isProcessingTasks = true;
}
if (startProcessing)
{
// start task processing
Task.Factory.StartNew(ProcessTasks);
}
// wait until our task is done
waitHandle.WaitOne();
}
private static void ProcessTasks()
{
while (true)
{
Action task;
ManualResetEvent waitHandle;
lock (syncRoot)
{
if (tasks.Count == 0)
{
// all done
isProcessingTasks = false;
break;
}
var pair = tasks.Dequeue();
task = pair.Key;
waitHandle = pair.Value;
}
// perform the task
task();
// signal that we are done
waitHandle.Set();
}
}
}
答案 0 :(得分:0)
单AutoResetEvent
就足够了:
public static class SynchronizedWorker
{
private static AutoResetEvent waitHandle = new AutoResetEvent(false);
public static void ProcessTask(Action task)
{
if (waitHandle.WaitOne())
{
Task.Factory.StartNew((() =>
{
// process task
task();
// signal that we are done
waitHandle.Set();
}));
}
}
}
答案 1 :(得分:0)
我不确定这是否100%正确,因为
NR。 2表示当前线程将被阻止,并且不会在&#34;任务中完成#34;方式。也许这正是你想要的,但是对于开始&#34;一些&#34;任务和继续,但只是希望这些任务开始,如果其他人完成,这还不够。