问题
I have four level data structure defined like this:
Dictionary<Type1, Dictionary<Type2, Dictionary<Type3, List<Type4>>>>
The whole thing is encapsulated in a class which also maintains thread-safety. Currently it just locks whole collection while it reads/manipulates the data (reading is by orders of magnitude more common than writing).
I was thinking of replacing the Dictionary
with ConcurrentDictionary and List
with ConcurrentBag (its items don't have to be ordered).
If I do so, can I just eliminate the locks and be sure the concurrent collections will do their job correctly?
回答1:
The concurrent collections will prevent data corruption and crashes, but the code won't be semantically equivalent to your current one. For example, if you iterate one of the concurrent dictionaries, some of the items may belong to different updates:
The enumerator returned from the dictionary is safe to use concurrently with reads and writes to the dictionary, however it does not represent a moment-in-time snapshot of the dictionary. The contents exposed through the enumerator may contain modifications made to the dictionary after GetEnumerator was called.
If you want to maintain the exact behavior you have now, yet save on the cost of locking, you may want to lock with ReaderWriterLockSlim which is especially suited for cases with more reads than writes.
回答2:
I'm nearly a year late to the question.. but just in case anyone finds themselves in a similar position to Matěj Zábský, ask yourself:
Can you use a Dictionary<Tuple<Type1, Type2, Type3>, List<Type4>>
instead?
Considerably easier to work with, and considering that hash tables (ie Dictionaries) are O(1) data structures with a somewhat hefty constant component (even more so if you move to a ConcurrentDictionary
) it'd likely perform faster too. It'd also use less memory, and be pretty trivial to convert to a ConcurrentDictionary
.
Of course if you need to enumerate all of a given Type2
for a given Type1
key, the nested dictionaries is possibly the way to go. But is that a requirement?
来源:https://stackoverflow.com/questions/4944018/is-multi-level-concurrentdictionary-still-thread-safe