0

I am using a BlockingCollection with a class of type T and I am wondering if I should turn T into a struct.

From the BlockingCollection signature in principle I do not see problems with that:

[DebuggerDisplay("Count = {Count}, Type = {m_collection}")]
[ComVisible(false)]
[DebuggerTypeProxy(typeof (SystemThreadingCollections_BlockingCollectionDebugView<>))]
[HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)]
public class BlockingCollection<T> : IEnumerable<T>, ICollection, IEnumerable, IDisposable

However, the semantic of blocking operation take supporting cancellation is that it returns null if the operation is cancelled before an element becomes available. The problem here is that a structure can't be null, so the following code is invalid

Struct myStruct = collection.Take(cancellationToken);
if(myStruct!=null) ... code

Are therefore blocking collections limited to classes, or does the semantic change returning a non-initialized struct?

Edmondo
  • 19,559
  • 13
  • 62
  • 115

2 Answers2

2

According to the documentation, Take doesn't return null if the operation is cancelled: an OperationCanceledException is thrown instead. Feel free to use any type, and be prepared to handle the exception if needed.

Julien Lebosquain
  • 40,639
  • 8
  • 105
  • 117
0

This has more to do with the behavior of structures vs classes. It's not only that a class can't be null, but it's also passed by value, not by reference. This means that each time you access an element of your collection, you'll get a copy of it instead of the original element.

This is the same for all collections, not just the blocking collections.

Regarding Take, as Julien notes, Take throws a OperationCanceledException, it doesn't return a null value. If you want to use Take you'll have to handle the exception whether you use a Struct or a Class.

A better alternative, especially if you expect frequent cancellatins, is to use TryTake instead of Take and check the result. e.g.

Struct myStruct;
if(collection.TryTake(out myStruct))
{
 ....
}
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236