Volatile weirdness
c#, multithreading
Solution
I think you have answer in your question:
due to compiler optimizations caching the value of complete and thus preventing the child thread from ever seeing the updated value.
Compiler/JIT optimizations are performed whenever it makes sense/deemed safe and reasonable to implement. So you found case when optimization is not performed the way you expect to happen - maybe there is a good reason (someone detected this usage pattern and block optimization) or it just happen not to be optimized (most likely).
Problem
I think most people are aware of the following issue which happens when building in Release mode (code taken from Threading in C#): ``` static void Main() { bool complete = false; var t = new Thread (() => { bool toggle = false; while (!complete) toggle = !toggle; }); t.Start(); Thread.Sleep (1000); complete = true; t.Join(); // Blocks indefinitely } ``` due to compiler optimizations caching the value of `complete` and thus preventing the child thread from ever seeing the updated value. However, changing the above code a bit: ``` class Wrapper { public bool Complete { get; set; } } class Test { Wrapper wrapper = new Wrapper(); static void Main() { var test = new Test(); var t = new Thread(() => { bool toggle = false; while (!test.wrapper.Complete) toggle = !toggle; }); t.Start(); Thread.Sleep(1000); test.wrapper.Complete = true; t.Join(); // Blocks indefinitely } } ``` makes the problem go away (i.e. the child thread is able to exit after 1 second) without the use of `volatile`, memory fences, or any other mechanism that introduces an implicit fence. How does the added encapsulation of the completion flag influence its visibility between threads?