简体   繁体   English

何时使用弱事件?

[英]When to use Weak Events?

I was refering MSDN tutorial on weak events. 我在弱事件上引用了MSDN教程。 I understood the basics. 我理解基础知识。 I am working on a non-WPF project and my class is exposing certain events. 我正在开发一个非WPF项目,我的课程正在暴露某些事件。 My question is that does the weak events completely replace old event pattern? 我的问题是弱事件是否完全取代旧的事件模式? Is it good to use it every classes that is exposing events? 每个暴露事件的类都使用它是否好? What are the side effects of using weak events liberally? 大量使用弱事件的副作用是什么?

Based on the reading I have done, there does not appear to be any specific negatives to using WeakEvents, except for the fact that it is more verbose to do so. 根据我所做的阅读,使用WeakEvents似乎没有任何具体的负面影响,除了事实上这样做更加冗长。 Additionally, you should be able, in most cases, to manually unregister from events when you no longer need them. 此外,在大多数情况下,您应该能够在不再需要时从事件中手动取消注册。 In some cases, this won't be possible. 在某些情况下,这是不可能的。 For example, the MSDN page you reference mentions when you should use WeakEvents: 例如,您引用的MSDN页面应该在您应该使用WeakEvents时提及:

http://msdn.microsoft.com/en-us/library/aa970850.aspx http://msdn.microsoft.com/en-us/library/aa970850.aspx

Certain scenarios inherently lend themselves to the application of the weak event pattern. 某些场景固有地适用于弱事件模式的应用。 One such scenario is data binding. 一种这样的场景是数据绑定。 In data binding, it is common for the source object to be completely independent of the listener object, which is a target of a binding. 在数据绑定中,源对象通常完全独立于侦听器对象,侦听器对象是绑定的目标。 Many aspects of WPF data binding already have the weak event pattern applied in how the events are implemented. WPF数据绑定的许多方面已经在事件的实现方式中应用了弱事件模式。

The only person who has presented any type of negative to them is this blog: 唯一一个向他们提出任何负面影响的人就是这个博客:

http://blog.catenalogic.com/post/2011/11/23/A-weak-event-listener-for-WPF-Silverlight-and-Windows-Phone-7.aspx http://blog.catenalogic.com/post/2011/11/23/A-weak-event-listener-for-WPF-Silverlight-and-Windows-Phone-7.aspx

There are a few downsides about using a weak event listeners in general: 一般来说,使用弱事件侦听器有一些缺点:

  • It's notation is ugly, the “original” .NET way looks way better 它的符号很难看,“原始”的.NET方式看起来更好
  • You have to name the event by string, that sucks (if you know a better way, contact me!) 你必须用字符串命名事件,这很糟糕(如果你知道更好的方法,请联系我!)
  • It can only handle events with a handler of EventHandler 它只能使用EventHandler的处理程序处理事件
  • You become a lazy developer not caring about subscriptions 你成为一个懒惰的开发人员,不关心订阅

Essentially, they should be used for events that your objects will subscribe to for the entire length of their existence, and only disconnect from when the objects are disposed. 从本质上讲,它们应该用于您的对象在其存在的整个长度内订阅的事件,并且仅在对象被处置时断开连接。 For everything else, using the traditional events and registering/unregistering the events manually is preferred. 对于其他所有内容,首选使用传统事件并手动注册/取消注册事件。

There are two issues that must be considered with weak events: 弱事件必须考虑两个问题:

  1. Weak events allow subscribers to subscribe to events (messages) even without knowing the identity of the class raising the event. 弱事件允许订阅者订阅事件(消息),甚至不知道引发事件的类的身份。 In some cases that may be desired even necessary. 在某些情况下甚至可能需要。 However, in some cases that can introduce unnecessary complexity and a level of indirection that makes the code harder to manage or control at run time. 但是,在某些情况下,可能会引入不必要的复杂性和间接性,从而使代码在运行时更难以管理或控制。
  2. The major downside of using weak events is that it may encourage developers to neglect the part where they unsubscribe from events (messages). 使用弱事件的主要缺点是它可能会鼓励开发人员忽略他们取消订阅事件(消息)的部分。 In that case event handlers may be invoked even after the subscribers "go out of scope". 在这种情况下,即使在订阅者“超出范围”之后也可以调用事件处理程序。 Consider a subscriber that does not explicitly unsubscribe and that becomes garbage collectable but was not yet garbage collected. 考虑一个没有明确取消订阅的订阅者,该订阅者可以收集垃圾,但尚未收集垃圾。 The weak event manager will not be able to detect that state and because of that it will still call the event handler of that subscriber. 弱事件管理器将无法检测到该状态,因此它仍将调用该订户的事件处理程序。 This can lead to all kind of unexpected side effects. 这可能会导致各种意想不到的副作用。

See more details at The Weak Event Pattern is Dangerous . 弱事件模式中看到更多细节是危险的
See this source code that illustrates this issue using the MvvMCross messaging plugin as a weak event manager. 请参阅此源代码 ,该代码使用MvvMCross消息传递插件作为弱事件管理器来说明此问题。

When to use weak events? 什么时候使用弱事件?

From MSDN 来自MSDN

Listening for events can lead to memory leaks 侦听事件可能会导致内存泄漏

So you should use weak events with the purpose of avoiding those leaks 所以你应该使用弱事件来避免这些泄漏

Is it good to use it every classes that is exposing events? 每个暴露事件的类都使用它是否好? What are the side effects of using weak events liberally? 大量使用弱事件的副作用是什么?

See Why is the implementation of events in C# not using a weak event pattern by default? 请参阅为什么C#中的事件实现默认情况下不使用弱事件模式? . Leaking from "strong" events is not that usual, weak events come with a performance cost and have a semantic difference that may not be desired in every context, misuse of a weak reference can cause the event to intermittently not to fire (in contrast to misusing a normal event causing a memory leak) 从“强”事件中泄漏并非通常情况,弱事件伴随着性能成本并且具有在每种情况下可能都不需要的语义差异,滥用弱参考可能导致事件间歇性地不发射(与之相反)滥用导致内存泄漏的正常事件)

Example memory leak that could be avoided 可以避免的内存泄漏示例

Static classes and Singletons are villains when talking about memory leaks, when they acquire a reference to some other object they will prevent the object from being garbage collected, and thus, leak the object forthe lifespan of the application, here is an example where I met with the need for a weak reference to avoid a memory leak 静态类和单身人士在讨论内存泄漏时是坏人,当他们获得对其他对象的引用时,他们将阻止对象被垃圾收集,从而在应用程序的生命周期内泄漏对象, 是我遇到的一个例子需要弱引用以避免内存泄漏

First of all, weak events are not always necessary, like others have been saying only when the source object outlive the subscriber. 首先,弱事件并不总是必要的,就像其他人一直说的那样,只有当源对象比订户更长时。 If that is the case, then yes, you should use it, this is what people call The Weak Event Pattern . 如果是这种情况,那么是的,你应该使用它,这就是人们所说的弱事件模式

The side effects are just that you will have to write more code. 副作用只是你必须编写更多的代码。 Microsoft provides the WeakEventManager class and in WPF exist some specific implementations, but you can create your own inheriting from the base WeakEventManager. Microsoft提供了WeakEventManager类,并且在WPF中存在一些特定的实现,但是您可以创建自己继承自WeakEventManager的基础。

The way it works is by using weak references from the source object to the listener so this relationship doesn't stop the GC from collecting these objects. 它的工作方式是使用从源对象到侦听器的弱引用 ,因此这种关系不会阻止GC收集这些对象。 For some specific applications this can solve a lot of performance issues. 对于某些特定应用程序,这可以解决许多性能问题。

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

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