我有一个跟踪对象的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();
我从这个网站学到了很多,并感谢任何回复! 感谢。
答案 0 :(得分:4)
在一个线程中从字典中获取和锁定值(ClientObject)是否意味着其他线程会尊重该锁定?换句话说,.net是否将字典中的值视为单个资源(而不是副本),因此会尊重所有线程中该资源的锁定?
它取决于类型 - 如果是引用类型则为yes,如果值类型为no。这也是你永远不应该锁定值类型的原因,因为值类型将被加框,并且任何后续锁定该值的尝试实际上将获取对另一个对象的锁定。
在从字典中删除资源时还有一个问题 - 我应该在执行Remove()
之前将其锁定
是的,你应该在任何改变对象状态的操作之前锁定。
作为旁注 - 您确定此设置是解决问题的最佳方法吗?跨线程共享的可变对象往往会在解决后产生更多问题。
答案 1 :(得分:1)
如果要在字典中添加或删除项目,请锁定字典。
当您将一个对象放入字典中时,您将在该字典中对该对象进行REFERENCE。为了防止第一个线程在更改它时第二个线程更改该对象,请锁定该对象,而不是字典。