Pet*_*etr 10 c# multithreading winforms
在我的多线程应用程序中,我使用的是一些可以在同一时间被许多实例更改的变量.这很奇怪,但它没有任何问题,但工作正常.但我当然需要让它具有线程安全性.我刚开始使用锁,所以我会建议你:
当客户端连接时,会创建类Client,其中每个客户端都有自己的"A"变量.
有时,客户端调用这样的方法:
Client selectedClient SelectOtherClientClassByID(sentID);
selectedClient.A=5;
Run Code Online (Sandbox Code Playgroud)
直到现在还没有问题,即使5个类同时进行(线程池),但我在考虑如何为A属性添加锁?
喜欢:
A {
get { return mA; }
set {
// use lock here for settting A to some value
}
}
Run Code Online (Sandbox Code Playgroud)
会没事吗?
NT_*_*NT_ 16
你需要在BOTH get和set中使用锁.此锁必须是同一个对象.例如:
private object mylock = new object();
public int A {
get {
int result;
lock(mylock) {
result = mA;
}
return result;
}
set {
lock(mylock) {
mA = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
锁定对访问者内部属性的访问可能会导致伪造结果.有关示例,请查看以下代码:
class C {
private object mylock = new object();
public int A {
get {
int result;
lock(mylock) {
result = mA;
}
return result;
}
set {
lock(mylock) {
mA = value;
}
}
}
}
C obj = new C;
C.A++;
Run Code Online (Sandbox Code Playgroud)
(是的,我从第一个答案中复制了它)这里有竞争条件!操作"C.A ++"实际上需要对A进行两次单独访问,一次获取值,另一次设置更新值.没有什么可以确保这两个访问将一起执行,而不需要在它们之间进行上下文切换.竞争条件的经典场景!
所以,要小心!把锁放在访问器中并不是一个好主意,应该明确获得锁,就像之前的答案所暗示的那样(虽然它不必与SyncRoots一起使用,任何对象都可以)