我在多线程应用程序中有一个通用字典;为了实现锁,我创建了一个属性。
static object myLock=new object();
Dictionary<key,SomeRef> dict=new Dictionary<key,SomeRef>();
public Dictionary<key,SomeRef> MyDict{
get{
lock(myLock){
return dict;
}
}
}
现在如果我写 CODE#1
MyDict.TryGetValue
或代码#2
var result=MyDict.Values;
foreach(var item in result){
//read value into some other variable
}
因此,当我运行代码 1 或 2 时,同时如果某个其他线程尝试对字典执行一些写操作,例如 ..clear dict 或添加新项目。那么,这个解决方案是否是线程安全的(使用属性)。 如果没有..那么还有其他方法可以做到这一点。
当我说写操作时,如果不创建键和赋值,它可以通过属性 chek key exoist 引用字典。 (因此我没有在属性中使用 setter)
最佳答案
不,这不是线程安全的。
锁只会锁定获取对字典的内部 (dict) 实例的引用。当用户尝试添加到字典或从字典中读取时,它不会锁定。
如果您需要提供线程安全访问,我建议将字典保密,并制定您自己的方法来从字典中获取/设置/添加值。这样,您就可以将锁放在适当的位置,以按照您需要的粒度进行保护。
这看起来像这样:
public bool TryGetValue(key thekey, out SomeRef result)
{
lock(myLock) { return this.dict.TryGetValue(thekey, out result); }
}
public void Add(key thekey, SomeRef value)
{
lock(myLock) { this.dict.Add(thekey, value) }
}
// etc for each method you need to implement...
这里的想法是您的客户直接使用您的类,而您的类处理同步。如果您希望它们迭代这些值(例如您的 foreach 语句),您可以决定是将这些值复制到一个列表中并返回它,还是直接提供一个枚举器 ( IEnumerator<SomeRef> GetValues()
),等等。
关于c# - 线程 :Lock on generic dictionary,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/730926/