动作委托和多线程同步

本文关键字:多线程 同步 | 更新日期: 2023-09-27 17:51:09

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

动作委托和多线程同步

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

不好的例子:

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();
}

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

public volatile Action Update;

不管线程,最好的做法是不要直接暴露成员,而是使用属性。然后需要将属性的后备存储设置为volatile,这就排除了自动属性:

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