我有一个多线程环境,其中包含需要同步调用(一个接一个)的特殊任务。
我制作了一个名为 SynchronizedWorker
的简单静态类,其中包含委托(delegate)和锁的 Queue
。它包含一个 ProcessTask
方法,可将新任务放入队列并等待任务完成。
它还包含 ProcessTasks
私有(private)方法,在单独的线程上处理所有任务。如果在新任务到达时它正在运行,则该任务就被放入队列中,我们等待。
为了通知调用者他的特定任务已完成,为该任务创建了一个 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();
}
}
}
最佳答案
一个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();
}));
}
}
}
关于c# - C#中的同步任务队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22261607/