8.4 Volatile fields
Like Java, C# has a volatile keyword for modifying fields only. This special modifier is usually used only in multi-threaded programming. Threads might cache the values of member fields for efficiency and, since threads can share the same field, it might be possible that a particular thread's cache field value is out of sync with the actual field's value. This is especially so if other concurrently running threads update the field of a shared object.
In both Java and C#, declaring a field as volatile tells the compiler that it should not attempt to perform optimizations (such as caching) on the field. The system always reads the current (latest) value of a volatile field at the point it is requested, and writes the value of the field immediately on assignment.
You declare a field as volatile by inserting the volatile keyword in front, as with all other modifiers. The following statement declares temp as a public static int variable which is also volatile: public static volatile int temp;
Like Java
You inform the compiler not to optimize a shared field by declaring it as volatile. You should declare fields which are shared by multiple concurrently-running threads as volatile ?this is especially so if this field is not synchronized within a lock block.
Additional notes
A volatile field cannot be passed to a ref or out parameter of a method (see section 7.2.2). The following will cause a compilation error:
1: class TestClass{
2: private volatile int MyInt;
3:
4: public void DoThis(ref int i){
5: }
6:
7: public static void Main(){
8: TestClass tc = new TestClass();
9: tc.MyInt = 3;
10: tc.DoThis(ref tc.MyInt);
11: }
12: }
Compilation error:
test.cs(10,19): error CS0676: Cannot pass volatile field
'TestClass.MyInt' as ref or out, or take its address
A volatile field cannot be read-only as well. The following declaration results in the compilation error 'A field can not be both volatile and readonly':
public readonly volatile bool b;
Likewise, you cannot declare a constant as volatile. The type of a field marked as volatile can only be of the following: - any reference type; - a pointer type (within an unsafe context) ?see section 9.1; - the following simple (primitive) types only: sbyte, byte, short, ushort, int, uint, char, float, bool; - an enum (see Chapter 25) type with an enum base type of sbyte, byte, short, ushort, int and uint.
 |