gpt4 book ai didi

c# - 为什么 C# 中用于线程安全事件调用的 "common"习语完全有效?

转载 作者:行者123 更新时间:2023-12-04 10:24:36 28 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Checking for null before event dispatching... thread safe?

(6 个回答)



Raise event thread safely - best practice [duplicate]

(10 个回答)


2年前关闭。




我正在阅读 Effective C#,我遇到了以下模式来改进事件调用行为并使其成为线程安全的:

    public class EventSource {
private EventHandler<int> Updated;
private int counter;

public void RaiseUpdates(){
counter++;
var handler = Updated;
if (handler != null){
handler(this, counter);
}

该书声称,由于在对 handler 的分配中存在“浅拷贝”。 , 来电 handler(this, counter)即使在其中一个退订之前的片刻,也会调用所有注册客户。 但是 C# 引用类型中的委托(delegate)不是吗?这个赋值不会为底层委托(delegate)对象创建一个新的引用吗?

最佳答案

委托(delegate)对象是不可变的,所以对它的引用的副本就可以了。对不可变对象(immutable对象)的引用的独立本地副本几乎是避免线程竞争问题的黄金标准。

当您添加/删除事件订阅时,Delegate.Combine等人创建一个每次更改时委托(delegate)实例(或 null,如果您取消订阅最后一个处理程序)并将对该新对象的引用(/null)分配给支持字段。这就是快照很有帮助的原因。

顺便说一句:在现代 C# 中,您可以使用 TheEvent?.Invoke(....) ,它会为您执行此操作。

关于c# - 为什么 C# 中用于线程安全事件调用的 "common"习语完全有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60678553/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com