【问题标题】:VB.NET: Do I need to call Thread.MemoryBarrier() before each read if I always complete my writes with Thread.MemoryBarrier()?VB.NET:如果我总是使用 Thread.MemoryBarrier() 完成写入,是否需要在每次读取之前调用 Thread.MemoryBarrier()?
【发布时间】:2026-01-15 19:55:02
【问题描述】:

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

【问题讨论】:

  • Volatile class 应该可以在 VB.net 中工作,Thread 类包含像 VolatileRead 这样的方法
  • 问题是我可以在读取之前安全地删除 Thread.MemoryBarrier() 以避免读取时可能不必要的内存栅栏成本。
  • 我敢肯定,如果你删除它,你会得到陈旧的读取。
  • 您无法删除它。顺便说一句,当您问这个问题时,您不太可能正确使用它。 Read this.
  • 那么这里的互联网有点冲突。请看:albahari.com/threading/part4.aspx(摘录:Thread 类中的静态 VolatileRead 和 VolatileWrite 方法在执行 volatile 关键字的保证(从技术上讲,是其超集)时读/写变量。不过,它们的实现效率相对较低,因为它们实际上会生成完整的栅栏)

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


【解决方案1】:

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

while (!IsDisposed); //reads _isDisposed

_isDisposed 的值可以清楚地缓存在此处的寄存器中,这样新的写入将永远不可见。此循环可能是无限的(例如 - 其他效果也可能是长延迟)。

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

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

struct VolatileInt32Box { public volatile int Value; }

【讨论】:

  • 我将使用 Hans Passant 提出的 VolatileRead/VolatileWrite 解决方案。
  • @dcarapic 出于某种原因,这两种方法要慢得多。它们编译为方法调用。它们只有缺点。
  • 不是根据 Hans pasant(他提供的链接 *.com/questions/27468923/…)。现在我还没有对此进行测试,但我从其他来源了解到 C# volatile 关键字和 VolatileWrite/VolatileRead 在功能和速度上应该相似。
  • 我几天前在当前的 4.5 JIT 和下一代 RyuJIT 上进行了测试。 RyuJIT 生成好的代码,当前的 JIT 继续令人失望。我建议不考虑性能:使用较新的功能(Volatile 类)。
最近更新 更多