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

jnm*_*nm2 5 c# multithreading

Volatile.ReadVolatile.Write对非易失性INT正常读取和任务对同一个int完全相同的效果volatile修改?

其动机是防止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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Jon*_*Jon 6

你的场景没有区别; 在谈论单个数组元素时,唯一的区别是:

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

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

  • 我想知道数组元素的波动性!甜!接下来,我将避开修饰符并始终通过Volatile和Interlocked显式访问变量.这样就没有关于访问类型的模糊性. (3认同)