C# - 从字典中获取资源时锁定资源

时间:2009-09-27 04:13:02

标签: c# dictionary multithreading locking

我有一个跟踪对象的Dictionary(ClientObject)。字典和ClientObject都由多个线程访问。当我修改或读取这个字典中的任何对象时,我使用ReaderWriterLockSlim(rwl_clients)获取字典上的读或写锁,然后获得对实际对象的独占锁。

我只是想知道我是否正确使用这些.net线程设施

示例:

rwl_clients.EnterReadLock();
ClientObject clobj;
if(!m_clients.TryGetValue(key, out clobj))
    return;
rwl_clients.ExitReadLock();

SomeMethod(clobj);

SomeMethod(ClientObject clobj)可以执行以下操作:

lock(clobj) {

/// Read / Write operations on clobj

}

在一个线程中从字典中获取和锁定值(ClientObject)是否意味着其他线程会尊重该锁定?换句话说,.net是否将字典中的值视为单个资源(而不是副本),因此会尊重所有线程中该资源的锁定?

在从字典中删除资源时还有一个问题 - 我应该在执行Remove()

之前将其锁定

示例:

rwl_clients.EnterWriteLock();
ClientObject clobj;
if(m_clients.TryGetValue(key, out clobj)) {
     lock(clobj) {
          m_clients.Remove(key);
     }
}
rwl_clients.ExitWriteLock();

我从这个网站学到了很多,并感谢任何回复! 感谢。

2 个答案:

答案 0 :(得分:4)

  

在一个线程中从字典中获取和锁定值(ClientObject)是否意味着其他线程会尊重该锁定?换句话说,.net是否将字典中的值视为单个资源(而不是副本),因此会尊重所有线程中该资源的锁定?

它取决于类型 - 如果是引用类型则为yes,如果值类型为no。这也是你永远不应该锁定值类型的原因,因为值类型将被加框,并且任何后续锁定该值的尝试实际上将获取对另一个对象的锁定。

  

在从字典中删除资源时还有一个问题 - 我应该在执行Remove()

之前将其锁定

是的,你应该在任何改变对象状态的操作之前锁定。

作为旁注 - 您确定此设置是解决问题的最佳方法吗?跨线程共享的可变对象往往会在解决后产生更多问题。

答案 1 :(得分:1)

如果要在字典中添加或删除项目,请锁定字典。

当您将一个对象放入字典中时,您将在该字典中对该对象进行REFERENCE。为了防止第一个线程在更改它时第二个线程更改该对象,请锁定该对象,而不是字典。