我的问题非常简短:
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()
{
//...
}
}
答案 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();
}
}
}