VB.NET:如果我总是使用 Thread.MemoryBarrier() 完成写入,是否需要在每次读取之前调用 Thread.MemoryBarrier()?

VB.NET: Do I need to call Thread.MemoryBarrier() before each read if I always complete my writes with Thread.MemoryBarrier()?

VB.Net 没有等效的 C# volatile 关键字,因此您必须手动实现 volatile,这通常通过在读取之前和写入之后调用 Thread.MemoryBarrier() 来完成。所以这样的事情相当于声明 C# volatile 变量:

    ''' <summary>
    ''' Gets a value indicating whether this instance is disposed.
    ''' </summary>
    Public Property IsDisposed As Boolean
        Get
            Threading.Thread.MemoryBarrier()
            Return _isDisposed
        End Get
        Private Set(value As Boolean)
            _isDisposed = value
            Threading.Thread.MemoryBarrier()
        End Set
    End Property

我想知道如果我写入变量的唯一地方是通过 setter 并且我总是在写入后调用 Thread.MemoryBarrier() ,那么读取之前的内存屏障是必要的。

我可以在阅读之前安全地删除 Thread.MemoryBarrier() 吗?

编辑:为了更清楚,我问我是否可以在读取之前删除 Thread.MemoryBarrier() 以消除每次读取的内存栅栏成本。

您无法移除读取端的障碍,这很容易通过示例显示。让我们使用这个 reader:

while (!IsDisposed); //reads _isDisposed

_isDisposed 的值可以清楚地缓存在此处的寄存器中,以便新写入永远不会可见。这个循环可能是无限的(例如 - 其他可能的影响,例如长时间延迟)。

更正式地说,_isDisposed 的读取都可以在存储发生之前及时移动 "upwards" 出现在 运行 上。 volatile 存储释放栅栏效果,这意味着以后没有任何东西可以越过它们。不过,事情可以通过它们移动到以前的时间点。

使用Volatileclass。或者,使用用 C# 编写的结构作为字段的包装器:

struct VolatileInt32Box { public volatile int Value; }