c# - 具有 AutoResetEvent 的生产者消费者

标签 c# multithreading waithandle

我正在尝试使用生产者消费者模式来处理和保存一些数据。我正在使用 AutoResetEvent 在两个 Therad 之间发送信号,这是我的代码

这是生产者函数

 public Results[] Evaluate()
    {
        processingComplete = false;
        resultQueue.Clear();
        for (int i = 0; i < data.Length; ++i)
            {
                if (saveThread.ThreadState == ThreadState.Unstarted)
                    saveThread.Start();
               //-....
               //Process data 
               // 
                lock (lockobject)
                {
                    resultQueue.Enqueue(result);
                }

                signal.Set();
            }
            processingComplete = true;
        }

这是消费者函数

   private void SaveResults()
    {
        Model dataAccess = new Model();

        while (!processingComplete || resultQueue.Count > 0)
        {
            if (resultQueue.Count == 0)
                signal.WaitOne();
            ModelResults result;
            lock (lockobject)

            {
                result = resultQueue.Dequeue();
            }
            dataAccess.Save(result);
        }
        SaveCompleteSignal.Set();
    }

所以我的问题是有时 resultQueue.Dequeue() 会抛出 InvalidOperation 异常,因为队列为空。我不确定我做错了什么,上面的 signal.WaitOne() 不应该阻止队列为空吗?

最佳答案

由于缺乏正确的锁定,您遇到同步问题。

您应该锁定所有队列访问,包括计数检查。

此外,使用Thread.ThreadState这种方式是一个“坏主意”。来自 ThreadState 的 MSDN 文档:

"Thread state is only of interest in debugging scenarios. Your code should never use thread state to synchronize the activities of threads."

您不能依赖此作为处理同步的方法。您应该重新设计以确保线程在使用之前启动。如果没有启动,就不要初始化它。 (您始终可以使用空检查 - 如果线程为空,则创建它并启动它)。

关于c# - 具有 AutoResetEvent 的生产者消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1882930/

相关文章:

c# - 如何计算文本文件中句子中的元音 (C#)

c# - 如何获得实际的监视器名称?如分辨率对话框中所示

c# - 将矩阵的每一行( float )转换为向量

c# - 从其他线程调用主线程中的方法

multithreading - 跨线程共享的连接的JDBC自动提交

c# - AutoResetEvent/ManualResetEvent 消耗什么资源?

c# - 我的 EventWaitHandle 说 "Access to the path is denied",但不是

c# - WaitHandle.WaitAny 和信号量类

c# - 为什么我的所有换行符都从 "/r/n"更改为 "/n/",我该如何阻止这种情况发生?

c# - Parallel Linq - 使用比处理器更多的线程(对于非 CPU 绑定(bind)任务)