Reading Joseph Albahari’s threading tutorial, the following are mentioned as generators of memory barriers:
- C#’s
lockstatement (Monitor.Enter/Monitor.Exit) - All methods on the
Interlockedclass - Asynchronous callbacks that use the thread pool — these include asynchronous delegates, APM callbacks, and Task continuations
- Setting and waiting on a signaling construct
- Anything that relies on signaling, such as starting or waiting on a Task
In addition, Hans Passant and Brian Gideon added the following (assuming none of which already fits into one of the previous categories):
- Starting or waking up a thread
- Context switch
Thread.Sleep()
I was wondering if this list was complete (if a complete list could even be practically made)
EDIT additions suggested:
- Volatile (reading implies an acquire fence, writing implies a release fence)
Here is my take on the subject and to attempt to provide a quasi-complete list in one answer. If I run across any others I will edit my answer from time to time.
Mechanisms that are generally agreed upon to cause implicit barriers:
Monitorclass methods including the C# keywordlockInterlockedclass methods.Volatileclass methods (.NET 4.5+).SpinLockmethods includingEnterandExit.Thread.JoinThread.VolatileReadandThread.VolatileWriteThread.MemoryBarriervolatilekeyword.QueueUserWorkItem,Task.Factory.StartNew,Thread.Start, compiler suppliedBeginInvokemethods, etc.ManualResetEvent,AutoResetEvent,CountdownEvent,Semaphore,Barrier, etc.Control.Invoke,Dispatcher.Invoke,SynchronizationContext.Post, etc.Mechanisms that are speculated (but not known for certain) to cause implicit barriers:
Thread.Sleep(proposed by myself and possibly others due to the fact that code which exhibits a memory barrier problem can be fixed with this method)Thread.YieldThread.SpinWaitLazy<T>depending on whichLazyThreadSafetyModeis specifiedOther notable mentions:
lockorInterlocked.CompareExchange.MarshalByRefObjectseems to suppress certain optimizations in subclasses which may make it appear as if an implicit memory barrier were present. Thanks to Hans Passant for discovering this and bringing it to my attention.11This explains why
BackgroundWorkerworks correctly without havingvolatileon the underlying field for theCancellationPendingproperty.