我从一个并行操作填充与CSV记录ConcurrentQueue(现在用我最好的收集选项?)包含ConcurrentQueue C#
ConcurrentQueue<string> bag = new ConcurrentQueue<string>();
"thisIsID123,they tossed an exception, error5678"
我没有看到一个“包含”在此收集方法。我怎样才能通过收集查看女巫项目有“thisIsID123”?
我从一个并行操作填充与CSV记录ConcurrentQueue(现在用我最好的收集选项?)包含ConcurrentQueue C#
ConcurrentQueue<string> bag = new ConcurrentQueue<string>();
"thisIsID123,they tossed an exception, error5678"
我没有看到一个“包含”在此收集方法。我怎样才能通过收集查看女巫项目有“thisIsID123”?
你不能轻易做到这一点。你可以用一个队列来做的就是队列,出列或枚举。要在队列中查找元素,您需要用完整的迭代进行蛮力搜索。
foreach(var element in myQueue)
{
//...
}
...或与LINQ
也许更合适的容器可能有帮助吗? C5系列提供可在FIFO模式下运行的HashedLinkedList。它提供了链接列表(例如队列)和哈希表中最好的一个,以便快速访问队列中间的元素。它不是为并发使用而设计的,所以你必须使用锁来同步你的读写操作。快速nuget,你会在你的指尖。
不知道你的问题域太多,我觉得把每进入一个ConcurrentBag<T>
或ConcurrentQueue<T>
(为什么?因为它是最有效的并发收集的插入,使极少数的假设有关预期使用)
(见here对于每个并发采集的优点)以及在数据采集完成后处理采集的内容可能是优选的。你当然不需要队列提供的顺序,因为并行循环中的处理顺序无论如何都是不确定的,所以你将会以半随机顺序将元素放入集合中。
所以,在回答您的意见,您可以收集在一个袋子里的一切:
var bag=new ConcurrentBag<Tuple<int, string>>();
var random=new Random();
//lets create some tuples to put in our bag
var objects = Enumerable
.Range(0, 1000000)
.Select(n= > Tuple.Create(n, n.ToString()))
.OrderBy(_ => random.Next())
.ToList();
Parallel.ForEach(objects, obj=>
{
bag.Add(obj);
});
然后进行查找出在包里的物品,使用特定属性作为键(这里我用元组的Item1
属性):
var lookup = bag.ToLookup(x=>x.Item1);
现在可以非常快速地查找其中的元组集合中有一个特定Item1
值。
IEnumerable<Tuple<int,string>> itemsOfInterest = lookup[3];
因为可能有多个项目共享相同的属性值,所以返回enumerable。
如果你能保证你的输入数据有没有重复,而不是做一本字典:
var dic= bag.ToDictionary(x=>x.Item1);
然后
var item = dic[3];
我读了ConcurrentBag在队列上的性能问题http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0 – nlstack01
@ nlstack01那篇文章是测量成本创建许多'ConcurrentBag
您是否介意在填充行李后,在Paralell.ForEach中显示填充行李的示例,然后根据上面的id获取元素? – nlstack01
你看不到'Contains',因为它并没有真正使没有意义用于队列。也许你想要一个'HashSet'?你将在这些字符串上做什么操作? –
ConcurrentQueue实现IEnumerable,那么包含LINQ扩展方法呢? –
@Yuval我想从一个并行操作中填充一个集合。这样做很好。有更好的选择吗? – nlstack01