1

I need for a queue which can be accessed simultaneously by 2 threads, one can be enqueueing an item while a different one is dequeueing another item. Does the Queue<T> class meet this requirement? Or should I implement it from scratch (for example using a single producer/consumer circular queue implementation like this)?

Community
  • 1
  • 1
enzom83
  • 8,080
  • 10
  • 68
  • 114

3 Answers3

4

If you're using .NET 4.0 you can use ConcurrentQueue. This is the recommended method.

Regarding Queue<T> itself, the MSDN page says the following (scroll down to the Thread Safety section:

A Queue can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. To guarantee thread safety during enumeration, you can lock the collection during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

Besides these solutions, you can implement your own thread safe queue. One way to achieve thread safety is immutability (though this will involve some locking). You can read about writing an immutable queue in Eric Lippert's blog, here. Alternatively, you can make use of the F#-based data types, most of which are immutable.

GregRos
  • 8,667
  • 3
  • 37
  • 63
  • I thought something lock-free like [this](http://www.codeproject.com/Articles/43510/Lock-Free-Single-Producer-Single-Consumer-Circular) – enzom83 Jun 25 '12 at 10:20
2

If you're implementing a consumer from the producer/consumer that you mentioned, then BlockingCollection is your friend. Otherwise, as others have said, ConcurrentQueue. BlockingCollection allows you to call .Take() when there are no elements to remove, and have it block, allowing a simplified consumer loop using just while (true).

Richard
  • 29,854
  • 11
  • 77
  • 120
1

The easiest way would be to use the ConcurrentQueue directly from Microsoft, if you're running .NET 4 that is. :)

Patryk Ćwiek
  • 14,078
  • 3
  • 55
  • 76