Thread.VolatileRead Method (Object%)
Updated: May 2011
Reads the value of a field. The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.
Assembly: mscorlib (in mscorlib.dll)
Parameters
- address
- Type: System.Object%
The field to be read.
VolatileRead and VolatileWrite are for special cases of synchronization. Under normal circumstances, the C# lock statement, the Visual Basic SyncLock statement, and the Monitor class provide easier alternatives.
On a multiprocessor system, VolatileRead obtains the very latest value written to a memory location by any processor. This might require flushing processor caches.
Even on a uniprocessor system, VolatileRead and VolatileWrite ensure that a value is read or written to memory, and not cached (for example, in a processor register). Thus, you can use them to synchronize access to a field that can be updated by another thread, or by hardware.
Calling this method affects only a single memory access. To provide effective synchronization for a field, all access to the field must use VolatileRead or VolatileWrite.
Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2
The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
And you may want this. Normally you can declare any reference-typed field to be volatile, and the compiler takes care of you. However, you can't do this to events. The default event add and remove handlers are lock-free and threadsafe, but to fire an event you must extract the delegate from it, and this has no special protection (though the CLR 2.0 memory model affords some extra protection).
Turns out there's less than meets the eye here. The implementation just copies the parameter into a local variable, then performs a memory barrier. You can perform a memory barrier yourself with Thread.MemoryBarrier(); so the generic version of VolatileRead() is
static T VolatileRead<T>(ref T obj) where T : class { T copy=obj; Thread.MemoryBarrier(); return copy; }
If you do this yourself, remember that the barrier follows the actual read, which is a little counter-intuitive. The idea is not to get the 'most recent' value of the field, but rather to ensure that no data can be extracted from the object it before we do read the reference to it (and therefore, perhaps before it was even initialized).
It seems intuitively impossible for the program to read the fields of the object before we read the reference to it, and indeed the CLR won't do it. But there are architectures where it is possible in theory: you just need a stale cache of the object's fields somewhere.
- 12/8/2011
- Daniel Normal Johnson