动作委托和多线程同步

时间:2013-01-10 12:03:17

标签: c# synchronization

我有字段public Action Update;,可以被多个线程调用。此字段也可以更改为null等。我应该创建一个属性并在其中使用锁定语句吗?或者当我将Update = new Action (...)设置为原子操作并且它不需要锁定时?

2 个答案:

答案 0 :(得分:4)

按照Anders的回答,但如果进行空检查以避免竞争条件,则需要将变量的值临时存储在局部变量中。

错误的例子:

if(myClass.Update != null)
{
    // Race condition if Update is set to null here by another thread
    myClass.Update();
}

很好的例子:

var updateMethod = myClass.Update;
if(updateMethod != null)
{
    // No race condition since we try to call
    // the same value that we checked for null
    updateMethod();
}

答案 1 :(得分:3)

在C#中设置引用是一个原子操作,因此不需要锁定。但是,您应该使Update引用为volatile,以确保在更改时在所有线程中正确刷新它:

public volatile Action Update;

无论是线程化,最好不要直接公开成员,而是使用属性。然后,您需要为属性volatile设置后备存储,这将排除自动属性:

private volatile Action update;

public Action Update
{
  get { return update; }
  set { update = value; }
}