在 C# 中线程化应用程序时锁定 类 和属性的正确方法

Proper method for Locking Classes and Properties when threading applications in C#

我要求编码约定以及在 class.

中对属性和方法使用锁定机制的正确方法

例如我有两个属性和两个方法:

public class FOO
{
private Guid uniqueIdentifier;
object _syncuniqueIdentifier = new object();
public Guid UniqueIdentifier 
{
       get 
       { 
        lock(_syncuniqueIdentifier)
        {
        return uniqueIdentifier;
        }        
    }
    set 
    { 
         lock(_syncuniqueIdentifier)
         {  
        uniqueIdentifier = value;
         }          
    }
}

private string userName;
object _syncuserName = new object();
public string UserName 
{
       get 
       { 
        lock(_syncuserName)
        {
        return userName;
        }        
    }
    set 
    { 
         lock(_syncuserName)
         {  
        userName = value;
         }          
    }
}

object _syncMyMethod = new object();
public void myMethod(object argument1, object argument2)
{
   lock(_syncMyMethod)
   {
   do work with argument1 and argument2
   }
}


}

我是否使用了正确的模式来实现线程,或者我应该改为放置一个对象 _syncLock 并锁定该对象的所有属性和方法? 这样做的编码标准是什么?

是的,假设字段是独立的并且经常更改,您使用的是有效模式。只要在锁下不会发生太多计算,使用单个锁对象也是合理的选择。

如果两个(或更多)字段依赖 属性 级别的锁定将不起作用(即使使用单个对象进行锁定)并且您应该在属性之外锁定或重组 API 以防止只修改一个 属性.

负责锁定的来电者:

// no locks here, all callers to lock
public class FOO {
   public Guid UniqueIdentifier {get;set;}
   public string UserName {get;set;}
}

// in caller code
usersLock = new object();
List<FOO> users = ...

lock(usersLock) 
{
    // modify/read users here.
    ...
}

备选方案API:

public class FOO {
  private object idLock = new Object();

  // immutable Id class
  public class Id {
   public Id(....){...}
   public Guid UniqueIdentifier {get; private set;}
   public string UserName {get; private set;}
  }

  private Id id;
  public Id { get {lock(idLock){ return id;}}
              set {lock(idLock){ id = value;}}
}

请注意,根据示例中的字段名称(UniqueIdentifierUserName),这些字段组合在一起并且在字段级别上锁定将仅提供 "no exceptions" 意义上的线程安全,但是让两个彼此不同步是微不足道的 - 因此可能需要使用上面概述的方法之一。