title: Does an EventWaitHandle have any implicit MemoryBarrier?
body: <p>New to this website, so let me know if I'm not posting in an accepted manner.</p>
  
  <p>I've frequently coded something along the lines of the sample below(with stuff like Dispose ommited for clarity.  ).  My question is, are the volatiles needed as shown?  Or does the ManualResetEvent.Set have an implicit memory barrier as I've read Thread.Start does?  Or would an explicit MemoryBarrier call be better than the volatiles?  Or is it completely wrong?  Also, the fact that the "implicit memory barrier behavior" in some operations is not documented as far as I've seen is quite frutrating, is there a list of these operations somewhere?</p>
  
  <p>Thanks,
  Tom</p>
  
  <p>:</p>
  
  <pre><code>class OneUseBackgroundOp
  {
  
     // background args
     private string _x;
     private object _y;
     private long _z;
  
     // background results
     private volatile DateTime _a
     private volatile double _b;
     private volatile object _c;
  
     // thread control
     private Thread _task;
     private ManualResetEvent _completedSignal;
     private volatile bool _completed;
  
     public bool DoSomething(string x, object y, long z, int initialWaitMs)
     {
        bool doneWithinWait;
  
        _x = x;
        _y = y;
        _z = z;
  
        _completedSignal = new ManualResetEvent(false);
  
        _task = new Thread(new ThreadStart(Task));
        _task.IsBackground = true;
        _task.Start()
  
        doneWithinWait = _completedSignal.WaitOne(initialWaitMs);
  
        return doneWithinWait;
  
     }
  
     public bool Completed
     {
        get
        {
           return _completed;
        }
     }
  
     /* public getters for the result fields go here, with an exception
        thrown if _completed is not true; */
  
     private void Task()
     {
        // args x, y, and z are written once, before the Thread.Start
        //    implicit memory barrier so they may be accessed freely.
  
        // possibly long-running work goes here
  
        // with the work completed, assign the result fields _a, _b, _c here
  
        _completed = true;
        _completedSignal.Set();
  
     }
  
  }
  </code></pre>