使用以下代码:
var dispatcherQueue = new DispatcherQueue();
long totalSum = 0;
Arbiter.Activate(
dispatcherQueue,
Arbiter.Interleave(
new TeardownReceiverGroup(),
new ExclusiveReceiverGroup(
Arbiter.Receive<ComputationCompleteResult>(
true,
portSet,
computationResult => totalSum += computationResult.Result
),
new ConcurrentReceiverGroup(
// Imagine that there is a persistent Receiver registered here
)
)
);
我是否需要围绕 totalSum += computeResult.Result 生成一个完整的内存屏障?ExclusiveReceiverGroup的Receiver注册中的handler会被线程池调用,因为dispatcherQueue不使用Dispatcher。我读过线程池为它调用的回调生成了一个内存屏障,但这是否只是保证回调引用本身的新鲜度?
ExclusiveReceiverGroup 不会与任何其他代码同时运行,因此通过computationResult.Result 递增totalSum 不必是原子的。我知道 Interlocked.Add 隐式生成一个完整的栅栏,但我只是想看看我是否可以不使用它而逃脱。
这是一个理论问题。我实际上没有像上面的示例代码那样的任何代码,也没有此类代码的任何用例。所以,我想避免“使用 Interlocked.Add 以防万一”的答案。这更像是一个“让我们学习新东西”的问题。