I discuss the volatile keyword in this post with respect to the .NET CLR. C and C++ have different semantics for the volatile keyword. Using volatile to guarantee atomicity is not recommended. In fact, exactly for that reason .NET restricts the use of volatile to the following types:
- Any reference type.
- Any pointer type (in an unsafe context).
- The types sbyte, byte, short, ushort, int, uint, char, float, bool.
- An enum type with an enum base type of byte, sbyte, short, ushort, int, or uint.
I recently encountered a situation where I found volatile useful. I have a state attribute that is being changed concurrently by several threads. If I read that value at some point while another thread has just changed it, without volatile, I may read a value that is stale because it is held in a CPU register or cache. By using volatile I force that value to be read from memory before being checked. Any write to that attribute is also immediately written to memory.
Any variable not declared as volatile can also be written to memory using Thread.VolatileWrite and read using Thread.VolatileRead.