Reading Joseph Albahari's threading tutorial, the following are mentioned as generators of memory barriers:
- C#'s
lock
statement (Monitor.Enter
/Monitor.Exit
) - All methods on the
Interlocked
class - 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)