title: Why volatile and MemoryBarrier do not prevent operations reordering?
body: <p>If I understand meaning of volatile and MemoryBarrier correctly than the program below has never to be able to show any result.</p>
  
  <p>It catches reordering of write operations every time I run it. It does not matter if I run it in Debug or Release. It also does not matter if I run it as 32bit or 64bit application.</p>
  
  <p>Why does it happen?</p>
  
  <pre><code>    using System;
      using System.Threading;
      using System.Threading.Tasks;
  
      namespace FlipFlop
      {
          class Program
          {
              //Declaring these variables as volatile should instruct compiler to 
              //flush all caches from registers into the memory.
              static volatile int a;
              static volatile int b;
  
              //Track a number of iteration that it took to detect operation reordering.
              static long iterations = 0;
  
              static object locker = new object();
  
              //Indicates that operation reordering is not found yet.
              static volatile bool continueTrying = true;
  
              //Indicates that Check method should continue.
              static volatile bool continueChecking = true;
  
              static void Main(string[] args)
              {
                  //Restarting test until able to catch reordering.
                  while (continueTrying)
                  {
                      iterations++;
                      var checker = new Task(Check);
                      var writter = new Task(Write);
                      lock (locker)
                      {
                          continueChecking = true;
                          checker.Start();
  
                      }
                      writter.Start();
                      checker.Wait();
                      writter.Wait();
                  }
                  Console.ReadKey();
              }
  
              static void Write()
              {
                  //Writing is locked until Main will start Check() method.
                  lock (locker)
                  {
                      //Using memory barrier should prevent opration reordering.
                      a = 1;
                      Thread.MemoryBarrier();
                      b = 10;
                      Thread.MemoryBarrier();
                      b = 20;
                      Thread.MemoryBarrier();
                      a = 2;
  
                      //Stops spinning in the Check method.
                      continueChecking = false;
                  }
              }
  
              static void Check()
              {
                  //Spins until finds operation reordering or stopped by Write method.
                  while (continueChecking)
                  {
                      int tempA = a;
                      int tempB = b;
  
                      if (tempB == 10 &amp;&amp; tempA == 2)
                      {
                          continueTrying = false;
                          Console.WriteLine("Caught when a = {0} and b = {1}", tempA, tempB);
                          Console.WriteLine("In " + iterations + " iterations.");
                          break;
                      }
                  }
              }
          }
      }
  </code></pre>