I just read this puzzling line in Peter Richtie blog and I need help to understand the meaning Prior to .NET 4.5 you really programmed to the .NET memory model
: http://msmvps.com/blogs/peterritchie/archive/2012/09/09/thread-synchronization-of-atomic-invariants-in-net-4-5.aspx
Has the 'usual' .NET memory model (such as the one discussed in Jeffrey Richter book CLR via C# edition 1 and 2 (I haven't read 3d)) changed in .NET 4.5?
Is there an article with conscious explanation?
The proper way to handle concurrency in .NET is based on a weak memory model. This hasn't changed in .NET 4.5.
Just because Itanium is no longer supported doesn't mean you can assume the stronger x86 or amd64 memory models. For instance, you have other weak memory model platforms, such as ARM.
Always remember that non-volatile reads to the same variable or field may be elided after the first one by the JIT compiler, in case it can prove there is no synchronization between reads (memory barriers, monitor lock of an object that is/was monitor unlocked, volatile read of a variable that was volatile written, Interlocked
operations on a variable). This respects the thread's point of view consistency.
The article you linked to shows examples where Microsoft .NET Framework's JIT compiler elides reads in e.g. while
loops that read a non-volatile variable without any synchronization point inside the loop. But remember, a JIT compiler could use whole program optimizations to generalize this elision between callers and callees.
As such, lock-free algorithms in .NET that read a variable or field without memory barriers, locks, volatile semantics or Interlocked
operations, on the premise that these reads will eventually see changes from other threads, are gambling with the JIT compiler. In essence, these algorithms are wrong in terms of portability.
Which makes me wonder, why do you ask this?