Introduction
The volatile keyword is a convenience keyword for those who need to access member variables of a class or structure in multi-threaded conditions.
The purpose of the volatile keyword is to tell the compiler that the variable you are marking as volatile may be accessed by multiple threads. There are certain optimizations that the csharp compiler makes when it compiles our code, and unless the variable is marked as volatile, the compiler will make optimizations assuming that the variable will only be accessed by one thread at a time.
Note. that the volatile keyword can only be used against the following types of data.
Reference types
Pointer types (in an unsafe context). Note that although the pointer itself can be volatile, the object that it points to cannot. In other words, you cannot declare a "pointer to volatile."
Types such as sbyte, byte, short, ushort, int, uint, char, float, and bool
An enum type with one of the following base types: byte, sbyte, short, ushort, int, or uint
Generic type parameters are known to be reference types
IntPtr and UIntPtr
Variables that are objects or structures will need to use other locking mechanisms. Only variables that are members of classes or structures can be declared as volatile.
To declare a variable volatile, just add volatile as one of the variable modifiers.
class Akshay
{
private volatile int m_multiThreadVar;
}
In the following example, there are two static fields one field is an object reference of string type, and the other is a volatile bool value type. In the Main method, a new thread is created, and the SetVolatile method is invoked. In SetVolatile, both the fields are set.
using System;
using System.Threading;
namespace VolatileInThreading
{
class class1
{
static string result;
static volatile bool done;
static void SetVolatile()
{
result = "Csharpcorner.com";
done = true;
}
static void Main(string[] args)
{
new Thread(new ThreadStart(SetVolatile)).Start();
Thread.Sleep(200);
if (done)
{
Console.WriteLine(result);
}
Console.Read();
}
}
}
Output
When multiple threads execute at once, this can cause serious problems. Please keep in mind that the volatile modifier does not force synchronization of loads and stores; instead, it simply tells the compiler not to change the order of accesses to the field. By eliminating reordering optimizations, the code becomes more predictable from a programmer's perspective.
Again, since this is an advanced csharp concept, this is probably something that most of you will not need to worry about using, especially in ASP.NET. However, there have been times when I've used multithreading in an ASP.NET application (for screen scraping performance) so it is not completely out of the realm of possibility for you to need to know something about how to do multi-threaded programming. If you do, you'll be glad you learned about the volatile keyword.
After studying more about volatile, I found three portable uses for volatile. I'll summarize them here.
Marking a local variable in the scope of a setjmp so that the variable does not rollback after a long
Memory that is modified by an external agent or appears to be because of a screwy memory mapping
Signal handler mischief.
We have another example in which a worker thread can be created and used to perform processing in parallel with that of the primary thread.
using System;
using System.Threading;
namespace VolatileInThreading
{
public class Worker
{
private volatile bool shouldStop;
public void DoWork()
{
while (shouldStop)
{
Console.WriteLine("Worker thread: working...");
}
Console.WriteLine("Worker thread: terminating gracefully.");
}
public void RequestStop()
{
shouldStop = true;
}
}
public class WorkerThreadExample
{
static void Main()
{
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
workerThread.Start();
Console.WriteLine("Main thread: starting worker thread...");
while (!workerThread.IsAlive) ;
Thread.Sleep(1);
workerObject.RequestStop();
workerThread.Join();
Console.WriteLine("Main thread: worker thread has terminated.");
Console.Read();
}
}
}
The Worker class contains a private volatile bool shouldStop field. The volatile keyword ensures that any reads or writes to this variable are atomic, preventing potential data inconsistencies in multi-threaded scenarios.
The Worker class has two methods.
DoWork. This method runs in a loop as long as the shouldStop variable is true. It prints a message indicating that it's working.
RequestStop. This method is used to request the worker thread to stop. It sets the shouldStop variable to true.
In the WorkerThreadExample class:
An instance of the Worker class is created as workerObject.
A new Thread named workerThread is created and started, running the workerObject.DoWork method.
The main thread then enters a loop waiting for the worker thread to become alive using workerThread.IsAlive.
After the worker thread is alive, there is a short delay (1 millisecond) using Thread.Sleep(1).
The main thread is called workerObject.RequestStop() to request the worker thread to stop its work.
The main thread then calls workerThread.Join() to wait for the worker thread to complete. This ensures that the worker thread terminates gracefully before proceeding.
Finally, a message is printed indicating that the worker thread has terminated, and the program waits for user input using Console.Read() before exiting.
Note. that there is a small issue in your code. The while (shouldStop) loop in the DoWork method should be changed to while (!shouldStop) to correctly exit the loop when shouldStop is true.
Here's the corrected code snippet for the DoWork method.
Output
FAQs
Q- What is the purpose of the volatile keyword in C#?
A- The volatile keyword in C# is used to indicate that a variable can be accessed by multiple threads and should not be cached, ensuring that reads and writes to the variable are atomic and that the latest value is always retrieved. It is often used to manage shared variables in multithreaded applications.
Q- What happens when you mark a variable as volatile in C#?
A- When you mark a variable as volatile, it tells the compiler and the CPU to ensure that all reads and writes to the variable are performed directly in memory, preventing any caching of the variable's value. This ensures that changes to the variable are immediately visible to all threads, making it safe for multithreaded access.
Q- Can volatile be used with all types of variables in C#?
A- No, volatile can only be used with certain types of variables, specifically those that are of reference type (e.g., classes) or are 32-bit or smaller value types (e.g., int, bool, etc.). It cannot be applied to larger value types or custom structs.
Q- Is the volatile keyword a replacement for locks and mutexes in multithreading scenarios?
A- No, the volatile keyword is not a replacement for locks and mutexes. While it ensures that reads and writes to the variable are atomic and prevents caching, it does not provide mutual exclusion or synchronization. Locks and mutexes are used to protect critical sections of code from concurrent access, while volatile is primarily used for simple variable access in a multithreaded environment.
Q- When should you use the volatile keyword?
A- The volatile keyword should be used when you have a shared variable that is accessed by multiple threads without the need for complex synchronization mechanisms like locks or when you need to ensure that the variable is always up to date across threads. It's typically used for simple flags or variables that need to be read or written from different threads without the need for fine-grained control over thread access.
Q- Can the volatile keyword be used in combination with other synchronization mechanisms like locks?
A- Yes, it's possible to use volatile in combination with other synchronization mechanisms like locks or Monitor to achieve specific multithreading behavior. For example, you might use volatile for a flag that signals when a resource is available and use locks to protect access to that resource.

Sandip G PatilPosted Jul 26, 2021, 5:02 PM
Nice article . well explained..
C# CornerPosted Mar 26, 2018, 5:21 AM
Whats new in this article just a resemble little bit from MSDN :) https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(volatile_CSharpKeyword);k(volatile);k(TargetFrameworkMoniker-.NETFramework,Version=v4.5);k(DevLang-csharp)&rd=true
Kevin MoralesPosted Jun 15, 2017, 1:42 PM
Can you use volatile variables with the Task<TResult> type?
Dixie MoPosted Sep 12, 2014, 4:42 PM
http://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(volatile_CSharpKeyword);k(volatile);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true
Vijay PrativadiPosted Dec 27, 2011, 7:40 AM
Good !!!