开发者

Periodically iterating over a collection that's constantly changing

I have a collection of objects that's constantly changing, and I want to display some information about the contents every so often (my application is multi-threaded, and differently threads are constantly submitting requests to modify an object in the collection, so it's unpredictable).

I开发者_如何学Gof I lock the collection, I can iterate over it and get my information without any problems - however, this causes problems with the other threads, since they could have submitted multiple requests to modify the collection in the meantime, and will be stalled. I've thought of a couple ways around this, and I'm looking for any advice.

  • Make a copy of the collection and iterate over it, allowing the original to continue updating in the background. The collection can get large, so this isn't ideal, but it's safe.
  • Iterate over it using a For...Next loop, and catch an IndexOutOfBounds exception if an item is removed from the collection while we're iterating. This may occasionally cause duplicates to appear in my snapshot, so it's not ideal either.

Any other ideas? I'm only concerned about a moment-in-time snapshot, so I'm not concerned about reflecting changes in my application - my main concern is that the collection be able to be updated with minimal latency, and that updates never be lost.


You might want to look into using some concurrent collections from System.Concurrent namespace, if you are using .NET Framework 4. For example iterators returned from the ConcurrentQueue<T> class represent a moment-in-time view of the collection and are not affected by change in the collection. Normal collection iterators will be invalidated by changes in the underlying collection. Otherwise, you have no choice, but to lock the collection first. Maybe there are third-party implementations of concurrent collections. But I have not looked into those. Here is information on thread-safe collections in .NET Framework 4.

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


I tend to use your first option, making an array with .ToArray() and iterating over that. Have you profiled it to see how slow it is making a copy? It's usually been negligible for me, even for large collections.


Making a copy of the collection typically requires you to lock the collection first, so no gain here compared with just locking it and iterating over it - unless your collection supports some sort of fast cloning.

I think an alternative can be to use different kinds of collections, ones that have better support for concurrent accesses, or an ability to return snapshots quickly. Another answer here linked to .net specific ones; if you're interested in implementing one yourself I would suggest this paper:

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜