gpt4 book ai didi

c# - 为什么C#中事件的实现默认不使用弱事件模式?

转载 作者:IT王子 更新时间:2023-10-29 04:43:51 25 4
gpt4 key购买 nike

这个问题可能会导致推测性的答案,但我认为在 中实现 event 背后有一个深思熟虑的设计决策。 .

中的事件模式只要事件的发布者还活着,订阅者就可以保持活着。因此,如果您不取消订阅,就会泄漏内存(好吧,不是真的泄漏 - 但内存会不必要地被占用)。

如果我想防止这种情况发生,我可以取消订阅事件或实现一个弱事件模式作为 proposed at MSDN .

由于事件模式导致了如此多的问题(对于初学者?),问题是:为什么决定发布者保持对订阅者的强引用,而不是让它们独立或允许开发人员显式地拥有 strongweak 修饰符?

已经有几个 questions这里关于这个主题和答案听起来很合理,但没有人真正回答为什么会这样。

最佳答案

其中一个原因当然是性能。 GC 句柄(为所有“奇异”引用提供支持,例如 WeakReference)会带来性能成本。弱事件比“强”事件慢,因为它们需要 GC 句柄。强事件(默认情况下)由存储委托(delegate)的实例字段实现。这只是一个普通的托管引用,与任何其他引用一样便宜。

事件应该是一种非常通用的机制。它们不仅仅适用于您可能有几十个事件处理程序的 UI 场景。在这样一个基本的语言特性中加入大量的复杂性和性能成本并不是一个明智的想法。

还有一个语义差异非确定性,这将由弱引用引起。如果将 () => LaunchMissiles() 连接到某个事件,您可能会发现导弹有时会被发射。其他时候 GC 已经带走了处理程序。这可以用 dependent handles 解决。这引入了另一个层次的复杂性。

请注意,您可以自己实现对订阅者透明的弱事件。从某种意义上说,事件就像属性一样,它们只是基于 addremove 访问器方法的元数据和约定。所以这(只是)一个关于 .NET 语言选择的默认值的问题。这不是 CLR 的设计问题。

我个人发现很少有事件的强引用性质成为问题。通常,事件连接在具有相同或非常相似生命周期的对象之间。例如,您可以在 ASP.NET 中的 HTTP 请求上下文中连接所有您想要的事件,因为当请求结束时,所有 都将符合收集条件。任何泄漏的大小和生命周期都是有限的。

关于c# - 为什么C#中事件的实现默认不使用弱事件模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29064682/

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