BlockingCollection.TakeFromAny方法适合构建阻塞优先级队列吗?

13
我需要建立一个阻塞式优先队列,我的直觉是TakeFromAny可能是关键因素,但是该方法的文档很少。它的目的/适当使用方式是什么?
我的要求是多个线程将添加到高优先级或低优先级队列中。一个线程将始终从高优先级队列中获取,然后是低优先级队列。
很可能BlockingCollectionTakeFromAny方法对我没有用处。如果是这样,那么指向正确方向的指针将不胜感激。
1个回答

13

你说得对,这份文档确实比较简略。不过,我通过 Reflector 查看了实现代码,我认为你可以使用 BlockingCollection.TakeFromAny 方法来模拟你所需的优先级偏差。原因是该实现使用了 WaitHandle.WaitAny 方法,该方法返回所有已发出信号对象的最小索引。这意味着如果有两个或两个以上具有可用项的队列,则始终会选择出现在数组中的第一个队列。

以下代码应始终输出 "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);

1
感谢Brian的及时回复。你的答案与我观察到的一致。现在我的担忧是,由于这种行为没有记录,我使用它并相信它不会从一个版本到另一个版本改变,这样会有多大的风险? - Ralph Shillington
1
@Ralph:我理解你的担忧。我怀疑这正是微软想要的行为,所以我的直觉是它将始终如此。不过,把这个关键信息添加到文档中以确认肯定会很好吧? - Brian Gideon
2
如果这是微软想要的行为,那么它不应该被称为“TakeFromFirstAvailable”吗? - Gabe
1
@Gabe --- 我认为你是对的,TakeFromAny 表明任何集合都一样好,因此我所依赖的行为可能会在未来版本中被“修复”。不知道获得微软澄清此方法意图的最佳方式是什么。 - Ralph Shillington
1
@Gabe:说得好。我想你同样可以对WaitHandle.WaitAny方法提出类似的论点。 - Brian Gideon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接