What Interlocked.CompareExchange is used for in the dapper .net method?
.net, c#, dapper, thread-safety
Solution
They want to do a volatile read however there is no overload of `Thread.VolatileRead` that takes a generic type parameter. Using `Interlocked.CompareExchange` this way achieves the same result.
The problem they are trying to solve is that the JIT compiler can optimize away the assignment to a temp if it sees fit. This can cause threading problems if another thread mutates the head reference while the current thread is using it in a sequence of operations.
Edit:
The issue is not that a stale value is read at beginning of `TryAdd`. The problem is that on line 105 they need to compare the current head to the previous head (held in `snapshot`). If there is an optimization then there is no `snapshot` variable holding the previous value and `head` is read again at that point. It is very likely that `CompareExchange` succeeds even though head might have changed between lines 103 and 105. The result is that a node in the list is lost if two threads call `TryAdd` simultaneously.
Problem
In dapper code in `Link.TryAdd` method, there is the following piece of code: ``` var snapshot = Interlocked.CompareExchange(ref head, null, null); ``` Why is this required instead of simple: ``` var snapshot = head; ``` both lines do not change the value of `head`, both lines assign the value of `head` to `snapshot`. Why the first one was chosen over the second? Edit: the code I'm referring to is here: https://github.com/SamSaffron/dapper-dot-net/blob/77227781c562e65c167bf7a933d69291d5bdc6f3/Dapper/SqlMapper.cs