2 cents on the concurrent collections
IProducerConsumerCollection<T>
IProducerConsumerCollection<T> is the starting point. It is an interface derived from ICollection and IEnumerator<T>. Basically, these two interfaces are read only, so the new interface add TryAdd and TryTake methods. The others methods are a generic CopyTo and a ToArray.
I am not very found of the Add/Take semantics, as it is generally Add/Remove. I guess Push/Pull would have been better suited for a Producer/Consumer interface.
I also believe CopyTo to be dangerous. How do I know which size to allocate for the array when it could very well change before I call CopyTo ?
And last, but not least, how do I know that the producer is done producing?
ConcurrentBag<T>, ConcurrentStack<T>, ConcurrentQueue<T>
These are the 3 collections implementing the IProducerConsumerCollection interface:
ConcurrentBag, when no specific ordering is required to take from the collection;ConcurrentStack, when you want to take the last produced item first;ConcurrentQueue, when you want to consume in the order it was produced.
These collections implement an IsEmpty property, suggesting that the Count property is not in constant time.
BlockingCollection<T>
The BlockingCollection is a wrapper for the Producer/Consumer interface. It provides Add/Take helpers and a GetConsumingEnumerator() function to consume in a for each loop.
It also add TryAddToAny and TryTakeFromAny static functions. This I do not get. Why not using composition instead of static functions.