我的问题实际上是this的扩展。在返回属性之前,关于测试属性的问题是null。我有类似的情况:
public class MyClass
{
private readonly string _Name { get; set; }
private readonly IEnumerable<T> _Values { get; set; }
private IEnumerable<T> _MyProp { get; private set; }
public IEnumerable<T> MyProp
{
get
{
if(_MyProp == null)
{
this.SetProp();
}
return this._MyProp;
}
private set;
}
public MyClass(string Name, IEnumerable<T> Values)
{
this._Name = Name;
this._Values = Values;
}
private void SetProp()
{
// Business logic using Name and Values
this._MyProp = resultOfLogic;
}
}
链接的SO问题的已接受答案提到这不是一种线程安全的方法。有人可以建议为什么它不是,有没有办法以线程安全的方式做到这一点?
答案 0 :(得分:4)
如果另一个线程正在运行,则该线程可以在测试和线程上SetProp()
的调用之间调用SetProp()
。
我使用这样的代码,以使其更安全:
// Dedicated object to lock for this property only
private object myPropSync = new object();
private T _myPropVal;
public IEnumerable<T> MyProp
{
get
{
// Check if property is null
if(_myPropVal== null)
{
// If null -> make sure you are the only one in the next section
lock (myPropSync) {
// Re-test, because another thread can
// set the property while waiting for the lock
if (_myPropVal== null) {
this.SetProp();
}
}
}
return this._myPropVal;
}
private set {
lock (_myPropSync) {
_myPropVal = value;
}
}
}
答案 1 :(得分:2)
有人可以提出建议吗
想象一下,有两个线程并行执行document.getElementById("rbtnZone").checked = true;
document.getElementById("rbtnZone").checked = false;
。
然后就可以得到这个序列:
get_MyProp
- &gt;真_MyProp == null
- &gt;真_MyProp == null
- &gt; _MyProp已初始化this.SetProp();
- &gt; T2重写_MyProp值,由T1 如果有以线程安全方式执行此操作的方法
转换this.SetProp();
而不是设置字段,并使用SetProp
(默认情况下,初始化为thread-safe):
IEnumerable<T>
答案 2 :(得分:0)
我认为您发布的代码可能存在错误。片段
public IEnumerable<T> MyProp
{
get
{
if(MyProp == null)
{ // ...
是无限递归的,会导致堆栈溢出(无资本化!)。
你的意思是最后一行使用_Values作为支持字段并测试null而不是MyProp?