3

When I call IProducerConsumerCollection<T>.TryAdd(<T>) or IProducerConsumerCollection<T>.TryTake(out <T>) will these ever fail because another thread is using the collection?

Or is it the case that if there is space to Add or something to Take even after the other thread has finished with the collection, it will always return true?

Nothing that I can see here: http://msdn.microsoft.com/en-us/library/dd287147.aspx

Cheetah
  • 13,785
  • 31
  • 106
  • 190

2 Answers2

6

While in theory the collections could reject take/add requests for any reason, the only reason I know about is Add failing because the collection has reached its capacity, and Take failing because the collection is empty.

The collections are designed from the get-go to be used from multiple threads - so if there are items left, even if two threads try to Take at the same time, they should both get an item and a return value of true.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • To expand on the above a little: the most prominent scenario using the `IProducerConsumerCollection` is `BlockingCollection`, and it uses the timeouts _only_ for the purpose of waiting for the collection to have room (for `TryAdd()`) or to have an element (for `TryTake()`). Contention is handled independent of the user-specified timeout. See e.g. http://referencesource.microsoft.com/#System/sys/system/collections/concurrent/BlockingCollection.cs,b4de4389b8938c7e – Peter Duniho Jul 03 '16 at 20:36
  • Since `BlockingCollection` doesn't implement the interface, this isn't exactly definitive, but it shows how Microsoft expects these methods to be implemented. The interface itself doesn't support timeouts (so timeouts obviously won't have bearing on success/failure), and even in the non-interface implementations in `BlockingCollection`, the timeouts relate only to the collection's full/empty state as in the non-timeout scenario, and nothing else. – Peter Duniho Jul 03 '16 at 20:37
0

For example, BlockingCollection<T> which is a high-level abstraction over the interface (it doesn't implement the interface though) with bounding and blocking capabilities may throw one of the following:

  • ObjectDisposedException on TryAdd(T) or TryTake(T) once the collection is disposed.
  • InvalidOperationException on TryAdd(T) if it's marked as complete for addition. Think about situation when you add values to a collection from 2 producers, one marks collection as complete, then another one tries to add to collection.
Andrey Taptunov
  • 9,367
  • 5
  • 31
  • 44