Q:

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

VB.Net does not have an equivalent of C# volatile keyword so you have to manually implement volatile which is usually done by calling Thread.MemoryBarrier() before read and after write. So something like this is equivalent to declaring C# volatile variable:
    ''' <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

I am wondering of the memory barrier before read is necessary if the only place where I write to the variable is through a setter and there I always call Thread.MemoryBarrier() after the write.
Can I safely remove the Thread.MemoryBarrier() before read?
Edit: To make it more clear I am asking if I can remove the Thread.MemoryBarrier() before read in order to remove costs of memory fence for each read.

A:

You can't remove the barrier on the read-side which is easy to show by example. Let's use this reader:
while (!IsDisposed); //reads _isDisposed

The value of _isDisposed can clearly be cached in a register here so that new writes will never become visible. This loop could be infinite (for example - other effects are possible such as long delays).
More formally, the reads of _isDisposed can all move "upwards" in time to appear to run before the store happens. volatile stores effect a release fence meaning that nothing can move over them later in time. Things can move over them to previous points in time, though.
Use the Volatile class. Or, use a struct written in C# as a wrapper around the field:
struct VolatileInt32Box { public volatile int Value; }

