c# - C#中的同步任务队列

标签 c# multithreading delegates queue

我有一个多线程环境,其中包含需要同步调用(一个接一个)的特殊任务。

我制作了一个名为 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/

相关文章:

c# - 为什么不能总是像函数一样传递委托(delegate)

ios - Swift : use of 'self' in method call before super. init初始化自编译报错

c# - 如何编写包含用户名的路由

c# - 在常用的实用程序函数中将 void 返回类型更改为其他类型有什么坏处吗?

c# - XML 序列化 - 处理特殊情况

c# - 对异步 WCF 的所有其他调用都很慢

python - 变量范围(带线程)

multithreading - 触发多个同步线程

java - AWT 中的 Java 线程池和 Java EventQueue 背后的概念是否有相似之处?

.net - 从语言上讲,逆变与委托(delegate)有什么关系?