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;
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. [8]
[8] A C# lock block is similar to a synchronized block in Java. A locked block is protected by an object mutex, and can only be assessed by any single thread at only one time. See Chapter 17.
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. [9]
[9] A volatile constant doesn't make sense since you cannot change a constant's value.
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.
3.144.102.69