volatile修饰符和Volatile.Read/Write有什么区别?

时间:2014-07-15 13:45:22

标签: c# multithreading

Volatile.ReadVolatile.Write对普通读取和赋值对volatile修饰符的int具有非易失性int的效果是否完全相同?

动机是防止volatile变量不应通过ref参数传递给Interlocked方法的警告。 (我知道该程序尽管有警告仍然是正确的,但我不想在我的代码中留下神秘的编译指示。)

//private volatile int suppressListChangedEvents;
private int suppressListChangedEvents;

public void SuppressListChangedEvents()
{
    Interlocked.Increment(ref suppressListChangedEvents);
}

public void UnsuppressListChangedEvents()
{
    if (Interlocked.Decrement(ref suppressListChangedEvents) < 0)
        throw new InvalidOperationException("Too many calls to unsuppress.");
}

protected override void OnListChanged(ListChangedEventArgs e)
{
    //if (suppressListChangedEvents != 0) return;
    if (Volatile.Read(ref suppressListChangedEvents) != 0) return;
    base.OnListChanged(e);
}

同样,我有一个使用Interlocked.Exchange(ref command, null)消耗命令的DirectX渲染线程泵,并且使用直接赋值给volatile command变量生成一些命令。我可以安全地将其更改为Volatile.Write并删除volatile修饰符而不会引入开销吗?

编辑:明确答案。 继续前进,我将避开修饰符并始终通过Volatile和Interlocked显式访问该变量。这样,代码对访问类型没有任何歧义;改变变量声明不会改变代码的含义。

在一个完美的世界中,我会通过让编译器拒绝直接引用或赋值给变量的能力来使volatile修饰符变得有用。这将迫使我将引用传递给Volatile或Interlocked或者本身使用Volatile或Interlocked的方法。我应该抓住罗斯林的副本。

1 个答案:

答案 0 :(得分:6)

您的情景没有区别;唯一的区别是when talking about individual array elements

  

在C#中,在字段上使用volatile修饰符可以保证每一个   访问该字段使用Volatile.ReadVolatile.Write   方法,但volatile修饰符不能应用于数组   元素。可以使用Volatile.ReadVolatile.Write方法   数组元素。

因此,只要您完全确定已捕获有关字段的所有用法,就可以安全地将毯子volatile更改为显式易失性读/写。< / p>