c# - C# 中的队列和等待句柄

标签 c# .net multithreading queue autoresetevent

多年来,我的应用程序中使用以下代码,但从未发现任何问题。

while ((PendingOrders.Count > 0) || (WaitHandle.WaitAny(CommandEventArr) != 1))
{
    lock (PendingOrders)
    {
       if (PendingOrders.Count > 0)
       {
           fbo = PendingOrders.Dequeue();
       }
       else
       {
           fbo = null;
       }
    }

    // Do Some Work if fbo is != null
}

其中 CommandEventArr 由 NewOrderEvent(自动重置事件)和 ExitEvent(手动重置事件)组成。

但我不确定这是否是线程安全的(假设 N 个生产者线程在入队前都锁定了队列,一个消费者线程运行上面的代码)。此外,我们可以假设 Queue.Count 属性仅从 Queue 类返回一个实例 Int32 值(没有 volatile 或 interlocked 或锁等)。

与 Queue 和 AutoResetEvent 一起使用的常用模式是什么来解决这个问题并执行我在上面的代码中尝试执行的操作?

(在正确指出 Queue.Count 可以执行任何操作及其具体实现后,对问题进行了轻微修改)。

最佳答案

在我看来线程安全,WaitAny() 将立即完成,因为事件已经设置。这不是问题。

不要破坏有效的线程同步。但是如果你想要一个更好的捕鼠器,那么你可以在这个 magazine article 中考虑 Joe Duffy 的 BlockingQueue。 .它的更通用版本在 .NET 4.0 中可用,System.Collections.Concurrent.BlockingCollection使用 ConcurrentQueue 作为它的实际实现。

关于c# - C# 中的队列和等待句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2741042/

相关文章:

c# 获取带有 "#"的完整 URL

c# - Visual Studio 2015 中的任务运行器可能性

c# - 如何在 64 位项目中引用 32 位 DLL?

linux - RT线程中的printf

java - 多线程 Hello World

C# Parallel.For 创建数组 : OK to put lock() on the array?

c# - 如何创建自定义数据网格

c# - 收集 Azure 中的 Service Fabric 群集日志

c# - 我必须在所有类上实现 IDisposable,还是一个基类就足够了?

c# - 任务并行库 (TPL) 是否处理竞争条件