定期迭代不断变化的集合

时间:2010-05-04 04:39:50

标签: .net multithreading collections iteration

我有一组不断变化的对象,我想经常显示一些有关内容的信息(我的应用程序是多线程的,不同的线程不断提交修改集合中对象的请求,所以这是不可预测的。)

如果我锁定集合,我可以迭代它并获得我的信息而没有任何问题 - 但是,这会导致其他线程出现问题,因为他们可能在此期间提交了多个修改集合的请求,并且停滞不前。我想到了几个方法,我正在寻找任何建议。

  • 制作该集合的副本并对其进行迭代,允许原始集合在后台继续更新。这个系列可能会变大,所以这不太理想,但它很安全。
  • 使用For ... Next循环迭代它,并在我们迭代时从集合中删除项目时捕获IndexOutOfBounds异常。这可能偶尔会导致重复出现在我的快照中,所以它也不理想。

还有其他想法吗?我只关注即时快照,所以我并不关心反映我的应用程序中的变化 - 我主要担心的是,集合能够以最小的延迟进行更新,并且更新永远不会丢失。

3 个答案:

答案 0 :(得分:2)

如果您使用的是.NET Framework 4,则可能需要考虑使用System.Concurrent命名空间中的某些并发集合。例如,从ConcurrentQueue<T>类返回的迭代器表示时刻集合的-time 视图,不受集合中更改的影响。 Normal 集合迭代器将因底层集合中的更改而失效。否则,您别无选择,只能先锁定集合。也许有并发集合的第三方实现。但我没有调查过那些。以下是.NET Framework 4中有关线程安全集合的信息。

http://msdn.microsoft.com/en-us/library/dd997305(v=VS.100).aspx

答案 1 :(得分:1)

我倾向于使用你的第一个选项,用.ToArray()创建一个数组并迭代它。你有没有想过看看制作副本的速度有多慢?对我来说,这通常是微不足道的,即使对于大型收藏品也是如此。

答案 2 :(得分:0)

制作该集合的副本通常需要您先锁定该集合,因此与仅锁定它并迭代它相比,这里没有任何好处 - 除非您的集合支持某种快速克隆。

我认为另一种选择可以是使用不同类型的集合,这些集合可以更好地支持并发访问,或者能够快速返回快照。这里的另一个答案与.net特定的答案有关;如果你有兴趣自己实施一个,我会建议这篇论文:

http://www.cs.tau.ac.il/~shanir/concurrent-data-structures.pdf