.net 4.0 Concurrent Collection的性能

时间:2012-10-26 09:08:45

标签: c# .net concurrency foreach

如果我们有一个ConcurrentBag<object> safeBag`填充了100个对象。

然后一个线程起作用:

   foreach(object o in safeBag)
{
    Thread.Sleep(1000);
}

另一个线程在第一个线程启动后立即启动:

{
    safeBag.AddOrTake(something);
}

第二个线程是否会等待100Sec进入资源? 另一个问题,如果第一个线程运行Parallel.ForEach(),线程将如何工作?

编辑:MSDN说:“只要集合没有被修改,List就可以同时支持多个读者。通过集合枚举本质上不是一个线程安全的过程。在极少数情况下枚举与一个或更多写访问,确保线程安全的唯一方法是在整个枚举期间锁定集合。“通过ConcurrentBag枚举是否会导致第二个线程在写入ConcurrentBag时等待写入?

2 个答案:

答案 0 :(得分:2)

对于大多数Concurrent*个集合,大多数操作都是原子操作,但不会持有任何长期锁定。在GetEnumerator()返回后,第一个线程不会阻塞第二个线程。

ConcurrentBag<T>.GetEnumerator Method

  

枚举表示行李内容的即时快照。调用GetEnumerator后,它不会反映对集合的任何更新。该枚举器可以安全地与读取和写入包同时使用。

答案 1 :(得分:0)

第二个线程,假设你正在连续产生两个线程 - 第一个使用ThreadStart指向包含迭代的块,第二个指向另一个代码块,不会等待1000ms 。 foreach块在移动到集合中的下一个对象之间只需等待1秒,第二个块不受此影响。

如果它是一个并行的foreach,那么在移动到下一个元素之前,你会有几个线程等待一秒(同时)。第二个区块仍然没有等待ConcurrentBag获得免费。