C#属性设置者是关键区域吗?

时间:2015-04-21 08:31:59

标签: c# multithreading race-condition

我的问题非常简短:
C#属性设置者是关键区域,还是应该自己实现关键区域?

以下是一些示例代码:

public class MyClass
{
    private int _myProperty;

    public int MyProperty
    {
        get { return _myProperty; }

        set
        {
            //required: start critical section 
            _myProperty = value;
            Do1();
            Do2();
            //required: end critical section 
        }
    }

    protected virtual void Do1()
    {
        //...
    }

    protected virtual void Do2()
    {
        //...
    }
}

2 个答案:

答案 0 :(得分:2)

,属性隐式线程安全。

一个原因是,对于非原子操作的线程安全性,需要锁定监视器对象(如lock语句中所示)。这是什么对象,以及锁定的时间长短取决于您的要求。因此,编译器无法自动为您决定。

另一个原因是线程安全性具有相当大的性能成本。如果您没有并发代码,这些成本将无益。因此,编译器也不会自动为您做出决定。

(事实上,属性并没有什么特别之处。它们通常是作为普通的get / set方法实现的。语法和工具中的任何特殊处理都只是按照惯例。)

答案 1 :(得分:2)

您应该自己实现关键区域,因为可能是在线程设置了属性之后但在处理Do1()和Do2()之前发生了上下文切换。另一个获得处理时间的线程现在可以覆盖你的财产。

使用锁来保护设置器:

private Object setMyPropertyLock = new Object()

public int MyProperty
{
    get { return _myProperty; }

    set
    {
        lock(setMyPropertyLock)
        {
            _myProperty = value;
            Do1();
            Do2();
        }
    }
}