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

时间:2015-01-14 08:59:30

标签: .net vb.net multithreading thread-safety memory-model

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(),以便为每次读取删除内存栅栏的成本。

1 个答案:

答案 0 :(得分:2)

您无法移除阅读侧的障碍物,该障碍物很容易通过示例显示。让我们用这个读者:

while (!IsDisposed); //reads _isDisposed

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

更正式地说,_isDisposed的读取都可以“向上”移动,以便在商店发生之前运行。 volatile存储会影响释放栅栏,这意味着以后什么都不能移动它们。但是,事情可以转移到以前的时间点。

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

struct VolatileInt32Box { public volatile int Value; }