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

Dal*_*pić 5 .net vb.net multithreading memory-model thread-safety

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

usr*_*usr 2

您无法消除读取端的障碍,这很容易通过示例来说明。让我们使用这个阅读器:

while (!IsDisposed); //reads _isDisposed
Run Code Online (Sandbox Code Playgroud)

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

更正式地说, 的读取_isDisposed都可以及时“向上”移动,看起来在存储发生之前运行。volatile商店会影响释放围栏,这意味着以后没有任何东西可以越过它们。不过,事情可以转移到之前的时间点。

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

struct VolatileInt32Box { public volatile int Value; }
Run Code Online (Sandbox Code Playgroud)