Question

I have the following code:

//In a Class:
private BlockingCollection<T>[] _collectionOfQueues;
// In the Constructor:
_collectionOfQueues = new BlockingCollection<T>(new ConcurrentQueue<T>())[4];

I get the following error for the bottom line:

Cannot apply indexing with [] to an expression of type 'System.Collection.Concurrent.BlockingCollection'

Even if I do:

_collectionOfQueues = new BlockingCollection<T>(new ConcurrentQueue<T>())[];

I get an error on the last square brace:

Syntax error; value expected

I am trying to make an array of BlockingCollection with the collection of ConcurrentQueue so that I can do:

_collectionOfQueues[1].Add(...);
// Add an item to the second queue

What am I doing wrong and what can I do to fix it? Can I not create an array of BlockingCollection and do I have to make a list of it?

Was it helpful?

Solution

You want to create a four element array of BlockingCollection<T> instances and you want to initialize each instance with a constructor that accepts a ConcurrentQueue<T> instance. (Note that the default constructor for BlockingCollection<T> will use a ConcurrentQueue<T> as the backing collection so you could get away by using the default constructor instead, but for demonstration purpose I'll stick with the construction from the question.)

You can either do this using a collection initializer:

BlockingCollection<T>[] _collectionOfQueues = new[] {
  new BlockingCollection<T>(new ConcurrentQueue<T>()),
  new BlockingCollection<T>(new ConcurrentQueue<T>()),
  new BlockingCollection<T>(new ConcurrentQueue<T>()),
  new BlockingCollection<T>(new ConcurrentQueue<T>())
};

Or you can do it using some kind of loop. Using LINQ is probably the easiest way to do it:

BlockingCollection<T>[] _collectionOfQueues = Enumerable.Range(0, 4)
  .Select(_ => new BlockingCollection<T>(new ConcurrentQueue<T>()))
  .ToArray();

Note that you in some way need to provide the code to initialize each element in the array. It seems that your problem is that you expect C# to have some functionality to create arrays with elements all initialized using the same constructor that you only specify once, but that is not possible.

OTHER TIPS

_collectionOfQueues = new BlockingCollection<ConcurrentQueue<T>>[4];
for (int i = 0; i < 4; i++)
    _collectionOfQueue[i] = new ConcurrentQueue<T>();

Declare as follows:

private BlockingCollection<ConcurrentQueue<T>>[] _collectionOfQueues;

Initialize as follows:

_collectionOfQueues = new BlockingCollection<ConcurrentQueue<T>>[4];
for (int i = 0; i < 4; i++)
    _collectionOfQueue[i] = new ConcurrentQueue<T>();

This has nothing to do with blocking-collections. The syntax you are using to create an array of a certain size and initialize its members isn't valid.

Try:

_collectionOfQueues = Enumerable.Range(0, 4)
                                .Select(index => new BlockingCollection<T>())
                                .ToArray();

By the way, you don't have to explicitly create a ConcurrentQueue<T> like that (just use the default constructor) as that is the default backing collection of a BlockingCollection<T>.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top