c# - 线程 :Lock on generic dictionary

标签 c# multithreading

我在多线程应用程序中有一个通用字典;为了实现锁,我创建了一个属性。

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/

相关文章:

java - 多线程 - 在创建新线程之前等待子线程 - Java

multithreading - C++11 加入第一个完成的线程

c# - 将数据的详细信息分组为一个,价格字段应该用分号分隔

c# - .Net Core App 2.0 与 .Net Standard 2.0 库不兼容

Python线程概念问题

python - 由于某些事件,例如,控制台程序是否有任何方法可以改变它们的执行方式按键或代码中的某些事件?

java - 如何从 JUnit 线程中断信号量?

c# - 当我从 'int' 类型的 sqlite 列中选择时,我可以转换为 .net int 但是当我从 'integer' 列中选择时,我不能

c# - 代码示例被证明在没有 volatile 的情况下会失败

c# - 如何在单元测试中使用 Moq 和 DbFunctions 来防止 NotSupportedException?