包含ConcurrentQueue C#

时间:2015-10-13 14:19:11

标签: c#

我正在使用并行操作中的CSV记录填充ConcurrentQueue(我是否使用了最佳收集选项?)

ConcurrentQueue<string> bag = new ConcurrentQueue<string>();

"thisIsID123,they tossed an exception, error5678"

我没有在此集合中看到“包含”方法。如何查看该集合以查看该项目有“thisIsID123”?

1 个答案:

答案 0 :(得分:2)

你不能轻易做到这一点。您可以对队列执行的任何操作都是队列,队列或枚举。要在队列中查找元素,您需要通过完整的迭代强制搜索它。

foreach(var element in myQueue)
{
    //...
}

...或LINQ

也许更合适的容器可能对此有所帮助? C5集合提供HashedLinkedList,可以在FIFO模式下运行。它提供了链接列表(例如队列)和散列表的最佳组合,以便快速访问队列中间的元素。它不是为并发使用而设计的,因此您必须使用锁同步读写。快速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];

您可以获得可枚举的数据,因为可能有多个项目共享相同的属性值。

如果您可以保证输入数据没有重复项,请改为输入字典:

var dic= bag.ToDictionary(x=>x.Item1);

然后

var item = dic[3];