我有两个BlockingCollection<T>
对象,collection1
和collection2
。我想要消耗这些集合中的物品,并优先处理collection1
中的物品。也就是说,如果两个藏品都有物品,我想首先从collection1
获取物品。如果他们都没有物品,我想等待物品可用。如何从任何两个BlockingCollections中获取优先于第一个集合的项目?
我有以下代码:
public static T Take<T>(
BlockingCollection<T> collection1,
BlockingCollection<T> collection2) where T:class
{
if (collection1.TryTake(out var item1))
{
return item1;
}
T item2;
try
{
BlockingCollection<T>.TakeFromAny(
new[] { collection1, collection2 },
out item2);
}
catch (ArgumentException)
{
return null;
}
return item2;
}
此代码有望重返null
时CompleteAdding
叫上两个集合,它们都是空的。
我用这个代码的主要问题是,对于TakeFromAny
方法的文档指定TakeFromAny
将引发ArgumentException
如果CompleteAdding
被称为的“集合”:
的ArgumentException
馆藏的说法是一个0长度的数组或包含一个null元素或CompleteAdding()已被调用集合。
如果在任何集合上调用CompleteAdding
,它会抛出吗?或两个集合?
如果CompleteAdding
被调用并且收集仍然有一些项目,它会抛出?
我需要一个可靠的方法来做到这一点。
在此代码中,我试图从collection1
开始,因为TakeFromAny
的文档没有对如果这两个集合具有项目的项目采集顺序提供任何保证。
这也意味着如果两个收藏都是空的,然后他们在同一时间收到物品,那么我可能会首先从collection2
获得物品,这很好。
编辑:
我之所以将项目添加到两个集合(而不是简单的单一集合)是第一个集合不具有上限,并且第二收集一样。
更多细节为那些有兴趣谁,为什么我需要这样的:
我在叫ProceduralDataflow一个开源项目使用此。在这里看到更多的细节https://github.com/ymassad/ProceduralDataflow
数据流系统中的每个处理节点有两个集合,一个集合将包含第一次进来的项目(所以我需要放慢生产者,如果需要),另一个集合将包含项目进入第二次(或第三次,......)次(由于数据流中的循环)。
一个集合没有上限的原因是我不想因数据流中的循环造成死锁。
谢谢。这样做是有道理的,但文件不清楚。在'TryTakeFromAnyCoreSlow'方法中,第5个条件表示“被标记为完成”。我假设这意味着'CompleteAdding'被调用并且集合是非空的。我将代码追踪到'GetHandles'方法,我认为情况就是这样。 –
我希望MSDN上有一些文档来澄清所有这些。 –
确实。基本上['IsCompleted'](https://msdn.microsoft.com/en-us/library/dd267315(v = vs.110).aspx)属性 - *此集合是否已标记为完成添加,并且空。* –