为什么不使用默认弱事件模式在C#中的事件执行?事件、模式

2023-09-03 02:24:08 作者:凡猪俗子

该问题可能导致投机性的答案,但我presume有中的 C#。

This question may lead to speculative answers but I presume there's a well thought design decision behind the implementation of event in c#.

在事件模式 C#不断用户活着,只要事件的发布者是活的。因此,如果你不退订,你泄漏内存(当然,不是真的泄漏 - 但记忆保持不必要的占用)。

The event pattern in c# 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).

如果我想prevent这一点,我可以退订事件或实现弱事件模式作为的在MSDN 建议。

If I want to prevent this, I can unsubscribe from events or implement a weak event pattern as proposed at 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?

目前已经有一对夫妇的questions这里关于这个话题,答案听起来合理,但没有真正解答了为什么很喜欢它。

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.

推荐答案

一个原因肯定是性能。 GC手柄(其中电源所有的异国情调的引用,如的WeakReference )配有性能损失。弱事件比强的事件更慢,因为它们需要一个GC手柄。强大的事件被执行(默认情况下),通过一个实例字段存储的委托。这只是一个普通的管理基准便宜,因为任何其他的参考。

One reason certainly is performance. GC handles (which power all of the "exotic" references such as WeakReference) come with a performance cost. Weak events are slower than "strong" events since they require a GC handle. 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.

事件被认为是一个非常普遍的机制。他们不只是意味着在你有可能几十事件处理程序的UI方案。这不是一个明智的想法烤了很多的复杂性和性能成本到这样一个基本的语言功能。

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. It is not a wise idea to bake a lot of complexity and performance cost into such a basic language feature.

此外,还有一个语义差别和非确定性这将是由弱引用造成的。如果挂钩()=> LaunchMissiles()的一些事件中,你可能会发现导弹能够被只是有时候启动。其他时候,GC已经带走处理。这可能与dependent处理其中引入了复杂性的另一个层次。

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. Other times the GC has already taken away the handler. This could be solved with dependent handles which introduce yet another level of complexity.

请注意,你可以自己透明地实现弱事件给用户。事件就像在这个意义上的属性,他们是根据各地的添加删除存取方法仅仅是元数据和惯例。因此,这(只)有关的.NET语言选择默认值的问题。这不是CLR的设计问题。

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. So this is (just) a question about the defaults that the .NET languages chose. This is not a design question of the CLR.

我个人觉得罕见的事件的强烈参考性是一个问题。通常情况下,事件被迷上了具有相同或非常相似的生命周期对象之间。例如,你可以连接所有的事件要在ASP.NET中的HTTP请求的情况下,因为所有的将有资格领取请求何时结束。任何泄漏是有界的规模和短暂的。

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. Any leaks are bounded in size and short lived.