起初我认为我确实需要写锁,但我不确定(没有多少经验)如果我不使用它。
在服务器端,每个连接的客户端都有客户端类。每个类都包含公共列表,其他每个类都可以写入。客户端请求通过线程池工作项处理。
class client
{
public List <string> A;
someEventRaisedMethod(param)
{
client OtherClient=GetClientByID(param) //selects client class by ID sent by msg sender
OtherCLient.A.Add("blah");
}
}
如果两个实例引用同一个客户端并且都尝试OtherCLient.A.Add(“blah”)怎么办?不是这里的一些作家锁吗?它适用于我,但我遇到一些我认为是由此引起的奇怪问题。
谢谢!
答案 0 :(得分:2)
(更新:一如既往,Eric Lippert及时blog entry)
如果您不使用锁定,则可能会丢失数据,状态损坏,可能会出现奇怪的Exception
- 但偶尔会出现 ,因此非常难以调试。< / p>
你绝对需要在这里进行同步。我会在客户端上公开一个锁(所以我们可以跨越多个操作):
lock(otherClient.LockObject) {
otherClient.A.Add("blah");
}
您可以在Add
上制作同步otherClient
方法,但跨越多个通常很有用 - 可能仅在缺少时检查Contains
然后Add
等
只是澄清2点:
lock
;否则它不起作用LockObject
应该是只读参考类型第二个,也许是:
private readonly object lockObject = new object();
public object LockObject {get {return lockObject;}}
答案 1 :(得分:0)
从我的观点来看,你应该做到以下几点:
答案 2 :(得分:0)
我不知道C#的内部结构,但我记得有一段时间回顾一下java示例,如果正在读取集合的同时正在对集合进行插入(我认为它是一个哈希表),所以请确保你使用多个线程来锁定读写。 Marc Gravell是正确的,你应该创建一个全局锁来处理这个,因为它听起来你的音量相当低。
ReaderWriterLockSlim也是一个很好的选择,如果你做了很多阅读并且只做了一些写/更新动作。