I have a Download Queue implemented with BlockingCollection<>
. Now I want to prioritize some Download once in a while. I thought it might be great to move some elements 'up' the Collection, like in a list, but there is no method like Remove()/AddFirst() or Move().
What's the preferred way of arranging items in a BlockingCollection<>
?
That being said, BlockingCollection<T> works upon any IProducerConsumerCollection<T> (specified in the constructor). If you don't provide one in the constructor, internally, it will use a ConcurrentQueue<T> . This causes it to be FIFO, since it will actually be (internally) a queue.
BlockingCollection<T> is a thread-safe collection class that provides the following features: An implementation of the Producer-Consumer pattern. Concurrent adding and taking of items from multiple threads. Optional maximum capacity. Insertion and removal operations that block when collection is empty or full.
Reed is correct in telling you that you need to implement the IProducerConsumerCollection<T>
. However, there is a class that can help you. It's not built in, but it's featured on MSDN. Just pass this ConcurrentPriorityQueue
to your BlockingCollection
.
This is how I used it:
private readonly BlockingCollection<KeyValuePair<int, ICommand>> _commands
= new BlockingCollection<KeyValuePair<int, ICommand>>(
new ConcurrentPriorityQueue<int, ICommand>());
The ICommand
is an interface in my project.
Now this allows you to add items like this:
_actions.Add(new KeyValuePair<int, ICommand>(1, command1));
_actions.Add(new KeyValuePair<int, ICommand>(2, command2));
_actions.Add(new KeyValuePair<int, ICommand>(1, command3));
Items with a lower integer value as priority will be executed first. In the above example:
command1
command3
command2
When looping over your BlockingCollection
, you will no longer get the single elements (ICommand
in my case), but a KeyValuePair
. This might require some code changes of course. A nice thing is that you have its original priority:
foreach (var command in _queue)
{
var priority = command.Key;
var actualCommand = command.Value;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With