C#-从字典中获取时锁定资源
我有一本跟踪对象(ClientObject)的字典。字典和ClientObject都由多个线程访问。当我修改或读取此词典中的任何对象时,我使用ReaderWriterLockSlim(rwl_客户端)获取词典上的读或写锁,然后获取实际对象上的排他锁 我只是想知道我是否正确使用了这些.net线程工具 例如:C#-从字典中获取时锁定资源,c#,dictionary,multithreading,locking,C#,Dictionary,Multithreading,Locking,我有一本跟踪对象(ClientObject)的字典。字典和ClientObject都由多个线程访问。当我修改或读取此词典中的任何对象时,我使用ReaderWriterLockSlim(rwl_客户端)获取词典上的读或写锁,然后获取实际对象上的排他锁 我只是想知道我是否正确使用了这些.net线程工具 例如: rwl_clients.EnterReadLock(); ClientObject clobj; if(!m_clients.TryGetValue(key, out clobj))
rwl_clients.EnterReadLock();
ClientObject clobj;
if(!m_clients.TryGetValue(key, out clobj))
return;
rwl_clients.ExitReadLock();
SomeMethod(clobj);
rwl_clients.EnterWriteLock();
ClientObject clobj;
if(m_clients.TryGetValue(key, out clobj)) {
lock(clobj) {
m_clients.Remove(key);
}
}
rwl_clients.ExitWriteLock();
SomeMethod(ClientObject clobj)将执行以下操作:
lock(clobj) {
/// Read / Write operations on clobj
}
在一个线程中从字典中获取并锁定一个值(ClientObject)是否意味着其他线程将遵守该锁?换句话说,.net是否将字典中的某个值视为单个资源(而不是副本),并因此在所有线程中对该资源进行锁定
还有一个问题,当从字典中删除资源时-我应该在执行Remove()之前锁定它吗
例如:
rwl_clients.EnterReadLock();
ClientObject clobj;
if(!m_clients.TryGetValue(key, out clobj))
return;
rwl_clients.ExitReadLock();
SomeMethod(clobj);
rwl_clients.EnterWriteLock();
ClientObject clobj;
if(m_clients.TryGetValue(key, out clobj)) {
lock(clobj) {
m_clients.Remove(key);
}
}
rwl_clients.ExitWriteLock();
我从这个网站学到了很多,非常感谢大家的回复!
谢谢
在一个线程中从字典中获取并锁定一个值(ClientObject)是否意味着其他线程将遵守该锁?换句话说,.net是否将字典中的某个值视为单个资源(而不是副本),并因此在所有线程中对该资源进行锁定
这取决于类型-如果是引用类型,则为是,如果是值类型,则为否。这也是为什么您永远不应该锁定值类型,因为值类型将被装箱,并且任何后续锁定该值的尝试都将实际获得对不同对象的锁定
还有一个问题,当从字典中删除资源时-我应该在执行Remove()之前锁定它吗
是的,您应该在任何改变对象状态的操作之前锁定
作为旁注-您确定此设置是解决问题的最佳方案吗?跨线程共享的可变对象往往会产生比它们解决的问题更多的问题。如果要从字典中添加或删除项,请锁定字典
当你把一个对象放在字典里时,你就是在字典里放一个对该对象的引用。要防止在第一个线程正在更改该对象时第二个线程更改该对象,请锁定该对象,不是字典。仅当它是引用类型时-OP的方法对值类型不起作用。如果我的字典被ReaderWriterLockSlim锁定,并且项目是引用类型,我会没事的谢谢您的回复!这真的为我澄清了事实:)