3

我有一个对象,它有大约 15 个字符串、十进制?日期时间?或int?我有一个从多个线程操作的此类的集合。我想确保以线程安全的方式访问(读/写)对象属性的值,同时编写最少的代码。有没有这样一种方法,而不是使用私人支持者并在每个属性的 getter 和 setter 中进行显式锁定?这是我现在必须为每个属性做的事情:

public class ManyProperties
{
    private Object mLock = new Object;
    private string _personName;
    public string PersonName {
        get {            
             lock (mLock){
                 return _personName;
             }           
        }
        set { 
             lock (mLock){
                  _personName = value; 
             }
        }
    }

    private string _beginAmount;
    public decimal? BeginAmount {
        get {            
             lock (mLock){
                 return _beginAmount;
             }           
        }
        set { 
             lock (mLock){
                  _beginAmount = value; 
             }
        }
    }
}
4

1 回答 1

4

属性通常不会孤立地工作。如果您无法获得正确且有效的值等,则让每个属性线程安全都无济于事。一个更合适的方法是让整个事情不可变,并让调用者得到一个快照

public class ManyProperties
{
    private readonly string _personName;
    public string PersonName { get { return _personName; } }

    private readonly decimal? _beginAmount;
    public decimal? BeginAmount { get { return _beginAmount; } }

    public ManyProperties(string personName, string decimal? beginAmount) {
       _personName = personName;
       _beginAmount = beginAmount;
    }
}

然后:

var snapshot = whatever.Properties;
var name = snapshot.PersonName;
...
var amount = snapshot.BeginAmount;

这些现在将始终保持一致。另外还有零锁。读取/更新引用也总是原子的 - 所以没有撕裂的值。

重要的是不要做:

var name = whatever.Properties.PersonName;
...
var amount = whatever.Properties.BeginAmount;

因为这里不再有任何保证name并且amount来自同一个ManyProperties实例:有人可能已经交换了两个提取之间的引用。

于 2013-02-19T18:56:20.067 回答