简体   繁体   English

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

[英]Why is the implementation of events in C# not using a weak event pattern by default?

This question may lead to speculative answers but I presume there's a well thought design decision behind the implementation of event in . 这个问题可能导致猜测性答案,但我认为在实现event背后有一个深思熟虑的设计决策。

The event pattern in keeps the subscriber alive as long as the publisher of the event is alive. 只要事件的发布者处于活动状态, 的事件模式就会使订阅者保持活动状态。 Thus, if you don't unsubscribe, you're leaking memory (well, not really leaking - but memory remains occupied unnecessarily). 因此,如果你没有取消订阅,你就会泄漏内存(好吧,并没有真正泄漏 - 但内存仍然不必要地占用)。

If I want to prevent this, I can unsubscribe from events or implement a weak event pattern as proposed at MSDN . 如果我想阻止这种情况,我可以取消订阅事件或实现MSDN中提出的弱事件模式。

With the event pattern causing so many problems (for beginners?), the question is: why was the decision made that the publisher keeps a strong reference to the subscriber, instead of making them independent or allowing developers to explicitly have a strong or weak modifier? 由于事件模式导致了很多问题(初学者?),问题是:为什么决定发布者保留对订阅者的强引用,而不是让它们独立或允许开发人员明确地拥有strongweak修饰符?

There are already a couple of questions here about this topic and the answers sound reasonable, but none really answers why it is like it is. 关于这个主题已经有了几个问题 ,答案听起来很合理,但没有一个真正回答为什么会这样。

One reason certainly is performance . 一个原因当然是表现 GC handles (which power all of the "exotic" references such as WeakReference ) come with a performance cost. GC句柄(为WeakReference等所有“异国情调”引用提供动力)会带来性能成本。 Weak events are slower than "strong" events since they require a GC handle. 弱事件比“强”事件慢,因为它们需要GC句柄。 A strong event is implemented (by default) by an instance field storing a delegate. 存储委托的实例字段(默认情况下)实现强事件。 This is just an ordinary managed reference as cheap as any other reference. 这只是一个普通的托管引用,与任何其他引用一样便宜。

Events are supposed to be a very general mechanism. 事件应该是一种非常通用的机制。 They are not just meant for UI scenarios in which you have maybe a few dozen event handlers. 它们不仅适用于您可能拥有几十个事件处理程序的UI场景。 It is not a wise idea to bake a lot of complexity and performance cost into such a basic language feature. 将很多复杂性和性能成本烘焙到这样一个基本语言功能中并不是一个明智的想法。

There also is a semantic difference and non-determinism that would be caused by weak references. 还存在由弱引用引起的语义差异非确定性 If you hook up () => LaunchMissiles() to some event you might find the missiles to be launched just sometimes. 如果您将() => LaunchMissiles()挂钩到某个事件,您可能会发现有时会启动导弹。 Other times the GC has already taken away the handler. 其他时候GC已经带走了处理程序。 This could be solved with dependent handles which introduce yet another level of complexity. 这可以通过引入另一个复杂程度的从属句柄来解决。

Note, that you can implement weak events yourself transparently to the subscriber. 请注意,您可以透明地向订户实施弱事件。 Events are like properties in the sense that they are mere metadata and conventions based around the add and remove accessor methods. 事件就像属性一样,它们仅仅是基于addremove访问器方法的元数据和约定。 So this is (just) a question about the defaults that the .NET languages chose. 所以这是(仅仅)关于.NET语言选择的默认值的问题。 This is not a design question of the CLR. 这不是CLR的设计问题。

I personally find it rare that the strong referencing nature of events is a problem. 我个人觉得很少有事件的强烈参考性质是一个问题。 Often, events are hooked up between objects that have the same or very similar lifetime. 通常,事件连接在具有相同或非常相似的生命周期的对象之间。 For example you can hook up events all you want in the context of an HTTP request in ASP.NET because everything will be eligible for collection when the request has ended. 例如,您可以在ASP.NET中的HTTP请求的上下文中挂接所有您想要的事件,因为在请求结束时, 所有内容都有资格进行收集。 Any leaks are bounded in size and short lived. 任何泄漏的大小都是有限的,而且寿命很短。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM