什么Interlocked.CompareExchange用于dapper .net方法?

And*_*ykh 3 .net c# thread-safety dapper

Link.TryAdd方法的dapper代码中,有以下代码:

var snapshot = Interlocked.CompareExchange(ref head, null, null);
Run Code Online (Sandbox Code Playgroud)

为什么这需要而不是简单:

var snapshot = head;
Run Code Online (Sandbox Code Playgroud)

两行都不改变值head,两行都赋值为headto snapshot.为什么在第二个选择第一个?

编辑:我所指的代码在这里:https://github.com/SamSaffron/dapper-dot-net/blob/77227781c562e65c167bf7a933d69291d5bdc6f3/Dapper/SqlMapper.cs

Mik*_*ray 7

他们想要进行易失性读取,但是没有过载Thread.VolatileRead需要泛型类型参数.使用Interlocked.CompareExchange这种方式可以获得相同的结果.

他们试图解决的问题是JIT编译器如果认为合适,可以优化分配给temp.如果另一个线程在当前线程在一系列操作中使用它时突变头引用,则会导致线程问题.

编辑:

问题不是在开头读取陈旧值TryAdd.问题是在第105行,他们需要将当前头部与前一个头部(保持在一起snapshot)进行比较.如果存在优化,则没有snapshot变量保持先前的值并且head在该点再次读取.CompareExchange即使行103和105之间的头部可能已经改变,也很可能成功.结果是如果两个线程TryAdd同时调用,则列表中的节点将丢失.