Working with the Volatile Keyword in C#

C# Programming Guide
The volatile keyword in C# is a modifier which, when applied to a field, indicates that the field might be modified by more than one thread concurrently. The compiler and runtime take special care when accessing volatile fields, ensuring that all threads see a consistent view of the field. This can be important for fields that are accessed by multiple threads without using proper synchronization.

Volatile fields are not given any special treatment by the CLR itself. They are subject to the same memory ordering rules as other fields. In particular, writes to volatile fields are visible to all threads in the system, regardless of whether they use locks or not. This can be important for code that needs to work correctly even in the face of incorrect use of locks.

It is important to note that the volatile keyword only applies to fields, and not local variables. Local variables are always stored on the thread’s stack, and so are not subject to concurrent modification by other threads.

Read: C# Tools for Code Quality

What is a Volatile Keyword?

The Volatile keyword is a C# keyword that is used to indicate that a field can be modified in the program by something outside of the program’s control, such as the operating system or hardware.

The Volatile keyword is used to prevent the compiler from optimizing code that accesses volatile fields in a way that could result in data corruption. The compiler must generate code that reads and writes volatile fields as if they were located in memory that could be written to by something outside of the program’s control. Volatile fields are often used for fields that represent hardware registers or other types of shared memory.

Why Do We Need the Volatile Keyword?

The Volatile keyword is used in multithreading to ensure that the value of a field is read from memory and not the cache. This ensures that you get the same value for reads and writes on a volatile variable, even if there is an optimization in place to make reads faster than writes. You can take advantage of the volatile keyword when you want to use variables or objects that are shared between threads.

The Volatile keyword does not prevent the compiler from reordering reads and writes in your code. It just ensures that the value of a field is the same as what’s in memory. This is done by preventing the compiler from caching the value in a register, so each thread sees its own copy of an object’s fields, rather than seeing cached values that were written earlier by another thread, before it could update them.

Read: Productivity Tools for .NET Developers

Volatile and Non-Volatile Memory Access

Modern systems have highly complex memory models. Several processors share processor registers, cache levels, and main memory. When your application runs, the CPU may store the data and then obtain it from the cache when the thread requests it. This data can be updated and read from the cached version while the main memory is updated later.

A thread may obtain an outdated version of the data when another thread simultaneously interacts with the same piece of data residing in the cache. When you alter the value of a non-volatile object, the change is performed in the thread’s cache rather than in the main memory. Contrary to this, when you alter the value of a volatile object, the execution thread cache and the primary memory are updated with the object’s current value.

Assume that two threads are accessing a variable. If the variable is non-volatile, each thread will store its own copy of the variable in the local cache. As a result, any change in the value of the variable by a thread will not be visible to the other thread. On the contrary, if the variable is volatile, the threads will not cache the variable. Now, if one of the threads has changed the value of the variable, both the threads will be able to get the updated value.

Let’s understand this with an example. Refer to the following C# code snippet:

int i = 1;
Console.WriteLine(i);

Since the variable i is non-volatile, any change made by a thread will be local to it. Now suppose the variable is volatile as shown below:

volatile int i = 1;

Now, suppose one of the two threads has changed the value of the variable:

i++;

When you display the value of the variable, it would print 2 (i.e., the updated value of the variable) for both the threads.

Programming the Volatile Keyword in C#

The following code shows how you can define a volatile variable in C#:

class Program
    {
        public volatile int x;
        static void Main(string[] args)
        {
            //Write your code here to work with the volatile variable
        }
    }
Here's another code example that illustrates how the volatile keyword can be used:
class MyVolatileClass
{
    public volatile int sharedVariable;
    public void MyVolatileClass(int i)
    {
        sharedVariable = i;
    }
}

Final Thoughts on the Volatile Keyword in C#

Although you can use the Volatile keyword with any pointer, or reference variables, you cannot use it with local variables. It should be noted that when you mark a reference object using the Volatile keyword, only the pointer to the object is volatile but not the content. In other words, the pointer that points to the object is volatile but not the content of the object itself.

You should note that the Volatile keyword is not a replacement for the lock keyword, i.e., for thread concurrency you still have to use the lock keyword. The Volatile keyword only helps you to avoid data inconsistency issues when multiple threads access the same piece of data.

By using the Volatile keyword, we specify that an object’s value must not be cached since its value may be altered by the operating system or hardware. Consequently, the compiler avoids performing any optimizations on the variable that might cause a data conflict, such as two threads accessing the variable simultaneously.

Read more C# programming tutorials and software development guides.

Joydip Kanjilal
Joydip Kanjilal
A Microsoft Most Valuable Professional in ASP.NET, Speaker, and Author of several books and articles. More than 25 years of experience in IT with more than 18 years in Microsoft .NET and its related technologies. He was selected as a Community Credit Winner at http://www.community-credit.com several times. He has authored 8 books and more than 500 articles in some of the most reputed sites worldwide including MSDN, Info World, CodeMag, Tech Beacon, Tech Target, Developer, CodeGuru, and more.

More by Author

Must Read