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. [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. 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. [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 . |