Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

66 changes: 34 additions & 32 deletions docs/csharp/language-reference/keywords/volatile.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "volatile (C# Reference)"
ms.date: 07/20/2015
ms.date: 10/24/2018
f1_keywords:
- "volatile_CSharpKeyword"
- "volatile"
Expand All @@ -9,42 +9,44 @@ helpviewer_keywords:
ms.assetid: 78089bc7-7b38-4cfd-9e49-87ac036af009
---
# volatile (C# Reference)
The `volatile` keyword indicates that a field might be modified by multiple threads that are executing at the same time. Fields that are declared `volatile` are not subject to compiler optimizations that assume access by a single thread. These restrictions ensure that all threads will observe volatile writes performed by any other thread in the order in which they were performed. There is no guarantee of a single total ordering of volatile writes as seen from all threads of execution.

The `volatile` modifier is usually used for a field that is accessed by multiple threads without using the [lock](../../../csharp/language-reference/keywords/lock-statement.md) statement to serialize access.

The `volatile` keyword can be applied to fields of these types:

- 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 known to be reference types.

- <xref:System.IntPtr> and <xref:System.UIntPtr>.

The volatile keyword can only be applied to fields of a class or struct. Local variables cannot be declared `volatile`.

The `volatile` keyword indicates that a field might be modified by multiple threads that are executing at the same time. The compiler, the runtime system, and even hardware may rearrange reads and writes to memory locations for performance reasons. Fields that are declared `volatile` are not subject to these optimizations. Adding the `volatile` modifier ensures that all threads will observe volatile writes performed by any other thread in the order in which they were performed. There is no guarantee of a single total ordering of volatile writes as seen from all threads of execution.

## Example
The following example shows how to declare a public field variable as `volatile`.
The `volatile` keyword can be applied to fields of these types:

[!code-csharp[csrefKeywordsModifiers#24](../../../csharp/language-reference/keywords/codesnippet/CSharp/volatile_1.cs)]
- 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."
- Simple 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 known to be reference types.
- <xref:System.IntPtr> and <xref:System.UIntPtr>.

Other types, including `double` and `long`, cannot be marked `volatile` because reads and writes to fields of those types cannot be guaranteed to be atomic. To protect multi-threaded access to those types of fields, use the <xref:System.Threading.Interlocked> class members or protect access using the [`lock`](lock-statement.md) statement.

The volatile keyword can only be applied to fields of a `class` or `struct`. Local variables cannot be declared `volatile`.

## Example
The following example demonstrates how an auxiliary or worker thread can be created and used to perform processing in parallel with that of the primary thread. For background information about multithreading, see [Managed Threading](../../../standard/threading/index.md) and [Threading (C#)](../../programming-guide/concepts/threading/index.md).
## Example

The following example shows how to declare a public field variable as `volatile`.

[!code-csharp[csProgGuideThreading#1](../../../csharp/language-reference/keywords/codesnippet/CSharp/volatile_2.cs)]
[!code-csharp[declareVolatile](~/samples/snippets/csharp/language-reference/keywords/volatile/Program.cs#Declaration)]

The following example demonstrates how an auxiliary or worker thread can be created and used to perform processing in parallel with that of the primary thread. For background information about multithreading, see [Managed Threading](../../../standard/threading/index.md) and [Threading (C#)](../../programming-guide/concepts/threading/index.md).

## C# Language Specification
[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]
[!code-csharp[declareVolatile](~/samples/snippets/csharp/language-reference/keywords/volatile/Program.cs#Volatile)]

With the `volatile` modifier added to the declaration of `_shouldStop` in place, you'll always get the same results (similar to the excerpt shown in the preceding code). However, without that modifier on the `_shouldStop` member, the behavior is unpredictable. The `DoWork` method may optimize the member access, resulting in reading stale data. Because of the nature of multi-threaded programming, the number of stale reads is unpredictable. Different runs of the program will produce somewhat different results.

## C# Language Specification

[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]

## See Also

- [C# Reference](../../../csharp/language-reference/index.md)
- [C# Programming Guide](../../../csharp/programming-guide/index.md)
- [C# Keywords](../../../csharp/language-reference/keywords/index.md)
- [Modifiers](../../../csharp/language-reference/keywords/modifiers.md)
- [C# language specification: volatile keyword](../../../../_csharplang/spec/classes.md#volatile-fields)
- [C# Reference](../index.md)
- [C# Programming Guide](../../programming-guide/index.md)
- [C# Keywords](index.md)
- [Modifiers](modifiers.md)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Links to the lock keyword and xref to the Interlocked would be useful here, for sure.

And maybe that blog post, as well:
https://blogs.msdn.microsoft.com/ericlippert/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three/

- [lock statement](lock-statement.md)
- <xref:System.Threading.Interlocked> class