13

I need to build a blocking priority queue and my hunch is that TakeFromAny may be the secret ingredient, however the documentation on that method is sparse. What is its purpose / appropriate use?

My requirement is that multiple threads will add to either a high priority or low priority queue. One thread will consume these two queues always taking from the high priority queue before the low priority queue.

It's quite possible that the neither the BlockingCollection or the TakeFromAny method will be of any use to me. If so, then a pointer in the right direction would be appreciated.

Theodor Zoulias
  • 15,834
  • 3
  • 19
  • 54
Ralph Shillington
  • 19,493
  • 20
  • 85
  • 150

1 Answers1

13

You are right. The documentation is rather sparse. However, I took a look at the implemenation via Reflector and I believe you can use the BlockingCollection.TakeFromAny method to simulate the priority bias you desire. The reason is because the implementation uses the WaitHandle.WaitAny method which returns the smallest index of all signaled objects. That means if you have two or more queues with items available then the queue appearing first in the array will always be chosen.

The following code should always output "high".

var low = new BlockingCollection<object> { "low" };
var high = new BlockingCollection<object> { "high" };
var array = new BlockingCollection<object>[] { high, low };
object item;
int index = BlockingCollection<object>.TakeFromAny(array, out item);
Console.WriteLine(item);
Brian Gideon
  • 45,093
  • 12
  • 98
  • 145
  • 1
    Thanks brian for this very timely response. Your answer agrees with what I was observing. My concern now is that since this behaviour is not documented, how much of a risk am I taking using trusting that it won't change from one version to the next? – Ralph Shillington Sep 13 '10 at 14:04
  • 1
    @Ralph: I understand your concern. I have a suspicion that this is the exact behavior Microsoft was after so my *hunch* is that it will always behave this way. It would definitely be nice to get that critical piece of information added to the documentation for confirmation though huh? – Brian Gideon Sep 13 '10 at 14:20
  • 2
    Wouldn't it be called `TakeFromFirstAvailable` if that was the behavior MS was after? – Gabe Sep 13 '10 at 14:39
  • 1
    @Gabe --- i think you're right, TakeFromAny suggests that any collection is as good as another, and so the behaviour I'm depending on could be "fixed" in a future version. Wonder what the best way is to get MS to clarify their intention for this method. – Ralph Shillington Sep 13 '10 at 15:46
  • 1
    @Gabe: Good point. I guess you could make a similar argument for the `WaitHandle.WaitAny` method as well. – Brian Gideon Sep 13 '10 at 15:46