使用字典时的线程安全性

12
如果我有一个 `

` 元素,其中包含一些文本和一个内联图片,则如何使这个图片垂直居中于元素的文本内容?

Dictionary<int, StreamReader> myDic = new Dictionary<int, StreamReader>
//Populate dictionary

一个线程执行

myDic[0] = new StreamReader(path);

另一个线程执行

myDic[1] = new StreamReader(otherpath)

如果实际上字典中的项与另一个线程上的不同,那么这是否是线程安全的,还是会出现InvalidOperationException: Collection was modified的异常?

3个回答

18

只有在同时修改并枚举字典时才会出现 InvalidOperationException: Collection was modified

然而,这并不是线程安全的。
如果其中一项操作导致字典调整大小,则其他操作可能会丢失。
相反,使用 ConcurrentDictionary


如果我有一个ConcurrentDictionary,并且需要检查containsKey,如果是True则执行某些操作:那么我仍然需要锁定它:lock (locker) {if (MyConDic.ContainsKey(toUserName)) {...}},是吗? - Royi Namir
@RoyiNamir:这样做完全违背了ConcurrentDictionary的初衷。请使用它的API。 - SLaks
但是谁能保证在第96行不会有另一个线程添加该条目?请详细说明。 - Royi Namir
@SLaks,Jon Skeet的这个答案似乎表明它可以与并行赋值一起使用:https://dev59.com/hXRB5IYBdhLWcg3weHLx - Matthew
@Matthew:不是的;那恰恰相反是他想表达的。 - SLaks
显示剩余2条评论

5

System.Collections.Generic集合仅当您从多个线程中读取时才是线程安全的。

引用自MSDN:

System.Collections.Generic集合类不提供任何线程同步;当在多个线程上同时添加或删除项目时,用户代码必须提供所有同步。

如果您想要对读写操作都实现线程安全,请考虑使用System.Collections.Concurrent

*编写新代码时,如果集合将被并发地写入多个线程,请使用并发集合类。*


1
为了改进你的代码,你可能想要查找 ConcurrentDictionary 类。它可以解决一些多线程问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接