锁定属性,好方法?

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)

  • 锁定它不是一个好主意,因为它可以从类型外部访问. (2认同)

小智 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一起使用,任何对象都可以)