我正在尝试使用生产者消费者模式来处理和保存一些数据。我正在使用 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/