问题标签 [weak-events]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
9083 浏览

.net - WPF 应用程序中使用的“弱事件”模式是什么?

WindowsBaseDLL 使用摘要定义事件IWeakEventListener

为希望通过 WeakEvent 模式和 System.Windows.WeakEventManager 接收事件的类提供事件侦听支持。

这种模糊的描述并没有描述“弱事件模式”实际上是什么。

那么,这种模式是什么,为什么要使用它,它在 WPF 应用程序之外有用吗?

编辑已经有一些很好的答案,但没有人谈论过这种模式在 WPF 应用程序之外是否有用。在我看来,弱事件模式(如依赖属性)与 WPF API 和 DLL 有着千丝万缕的联系。是否有可用于非 WPF 应用程序的等效实现?

0 投票
1 回答
1873 浏览

c# - 在 Windows.Forms 应用程序中使用 Wea​​kEventManager

当在 Windows.Forms 应用程序中使用此处描述的弱事件http://wekempf.spaces.live.com/blog/cns!D18C3EC06EA971CF!373.entry时,WeakEventManager 会泄漏 WeakReference 对象。我认为这是因为如果没有 WPF 消息循环,则永远不会执行 CleanupOperation,尽管在 WeakEventManager.ProtectedAddListener 中调用了 ScheduleCleanup。

作为一种解决方法,我实现了一个 Cleanup 函数,如下所示:

并在每次例如第 16 次调用ProtectedAddListener.

这行得通,但显然我喜欢避免这种(ab)使用反射。

所以我的问题是:

  1. 有没有办法使用公共/受保护的成员来实现清理功能?WeakEventManager.Purge 可能有用,但我不知道如何使用它。
  2. 有没有一种简单的方法可以在基于 Windows.Forms 的应用程序中运行 WPF 消息循环?
0 投票
2 回答
14727 浏览

.net - 使用 .NET 的 WeakEventManager 实现弱事件的示例

是否有使用 .NET 的WeakEventManager实现弱事件的示例?

我正在尝试按照文档中的“继承者说明”来实现它,但它是模糊的。例如,我无法弄清楚如何ProtectedAddListener从自定义管理器中的静态AddListener函数调用。

0 投票
2 回答
2091 浏览

wpf - WPF 控件是否在其绑定中使用弱事件?

当我在 WPF 中使用数据绑定时,我的目标控件正在侦听绑定源上的事件。例如,我可能会ListView监听CollectionChanged.ObservableCollection

如果预计事件源的生命周期会超过事件侦听器的生命周期,则存在潜在的内存泄漏,应使用弱事件模式。

WPF 数据绑定是否遵循弱事件模式?如果我的ObservableCollection寿命比我的长ListView,我会ListView被垃圾收集吗?


这就是为什么我怀疑 WPF 控件没有实现弱事件模式的原因。如果他们这样做了,我希望两者都DerivedListView Collected!输出DerivedTextBlock Collected!到控制台。相反,只有DerivedTextBlock Collected!是。

修复代码中的错误后,将收集两个对象。我不知道该怎么想。

Window1.xaml.cs

Window1.xaml

0 投票
2 回答
3509 浏览

c# - C# 语言:为什么是弱引用或弱事件模式?

我正在阅读“The C# Language”,第 4 版,它谈到WeakReferenceWeak Event Pattern

CHRISTIAN NAGEL:内存泄漏通常是由于事件的错误使用造成的。如果客户端对象附加到事件但不与它们分离,并且不再使用对客户端对象的引用,则垃圾收集器仍然无法回收客户端对象,因为发布者的引用仍然存在。这可以通过 (1) 在不再使用客户端对象时分离事件,(2)使用持有委托的类的addremove访问器的自定义实现,或 (3) WPF 使用 IWeakEventListener 来避免界面。WeakReferenceWeak Event pattern

我在这里有疑问:与“选项(1)显式分离事件”相比,选项“(2) WeakReference”根本没有带来任何便利WeakReference,因为使用仍然需要显式调用addand remove

否则,即使事件处理程序的对象之一被分配为 null,“孤儿”对象仍将响应该事件 - 这将导致意外行为。

注意:WeakReference仅以事件处理程序的对象不受事件发布者对象影响的方式帮助垃圾收集;WeakReference不强制事件处理程序对象被垃圾收集。

类似的问题也适用于弱事件模式。

也许这有点抽象,以 Josh Smith 的 Mediator 模式(http://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/)为例。

如果我们有

由于WeakReference?

但是如果Mediator该类提供“Unregister”方法(实际上我实现了一个),“选项(2)WeakReference”将与“选项(1)显式分离事件”没有区别。(Mediator 本身仍然是一个有用的模式,可以穿透 WPF 或 MVVM 组件层的层次结构)

0 投票
0 回答
108 浏览

events - 对于 INotifyPropertyChanged 的​​可放弃用户,是否有任何安全的非泄漏模式?

是否有任何模式可以让 INotifyPropertyChanged 的​​使用者避免内存泄漏,即使在特定 INotifyPropertyChanged 对象的生命周期内可以创建任意数量的使用者实例的情况下,也不会更改该对象的任何属性(因此通知触发)?事件发布者可以使用一些反射技巧来实现弱事件;是否有任何可行的订阅方弱事件模式?

如果事件合约要求事件发布者必须允许事件订阅者在任何时候从任何线程取消订阅,而不是无限期地阻塞,那么事件订阅者有可能让订阅者真正“感兴趣”的对象保留一个引用包装器对象,并让包装器对象覆盖 Finalize() 以告诉订阅者对象取消订阅。不幸的是,即使订阅者通过 Finalize() 发现它应该取消其订阅,.net 事件合约也不要求发布事件的对象必须允许它们从终结器中安全地释放。事实上,C# 的默认事件实现实际上从终结器中调用是不安全的(当前实现获取发布订阅的对象的锁;如果锁仅用于订阅和取消订阅,那不会有问题,但不能保证在任意时间长度内不会出于其他目的而持有锁)。早期的实现更糟糕:如果一个类尝试订阅或取消订阅它自己的事件,订阅和取消订阅根本就不是线程安全的。

如果知道 INotifyPropertyChanged 对象是某个特定的类,它以线程安全的方式实现其事件(对于订阅,获取锁,然后使用 Interlocked.Exchange 自旋循环;对于取消订阅,使用将获取lock 如果可用,但会尝试 Interlocked.CompareExchange 是否可用)可以安全地删除终结器中的事件处理程序。如果知道该对象会以某种显着频率引发事件,则可能会从事件中删除处理程序(尽管我不确定 .net 事件合同是否要求它也是安全的)。无论什么类型的 INotifyPropertyChanged 实现者被给予观察,是否有任何通用的解决方案可以工作?

编辑——澄清

这个想法不是一个对象会取消订阅它自己的终结器,而是对事件的影响感兴趣的对象将持有对包装对象的引用,事件处理本身不会持有对它的引用。例如,假设目标是计算使用特定事件名称字符串引发 PropertyChanged 事件的次数。可以有一个 PropertyChangeCounter 对象,它持有对 PropertyChangeCounter.Internals 对象的引用;后一个对象将保存事件订阅和更改计数。PropertyChangeCounter 对象的 ChangeCount 属性将返回嵌套 PropertyChangeCounter.Internals ChangeCount 的值。一旦没有外部人员持有对包装器对象的引用,包装器对象将有资格完成,

0 投票
1 回答
266 浏览

c# - C# 中的 WeakEvent 垃圾回收

我今天在考虑以下情况:

我有两个班A和B。

A 暴露了一个事件 E。

B 使用弱事件处理程序“W”订阅此事件“E”。

过了一会儿,没有人持有任何对 B 的引用,但 GC 还没有启动。

虽然 B 尚未被 GC 收集,并且 A 引发了“E”,但是否会调用弱事件处理程序?

我想是的,但如果我没有遗漏什么,我会很好奇。

0 投票
1 回答
850 浏览

silverlight - Silverlight 的弱事件的良好实现是什么?

我正在为 Silverlight 很好地实现弱事件模式以避免内存泄漏。那里似乎有一些实现,但代码并不简单,很难知道哪个是正确的。我找不到任何来自微软的官方推荐。

如果可能的话,我追求一个简单的语法。

干杯。

0 投票
1 回答
1032 浏览

c# - emddudley 的 WeakEventManager 的示例

我正在尝试将 Michael Dudley 的示例代码用于我自己的弱事件管理器实现:

使用 .NET 的 WeakEventManager 实现弱事件的示例

我想知道我将把我自己的处理程序的用户代码放在哪里?我看到这个:

我会用我自己的自定义代码替换那个表达式的内容吗?

谢谢,

凯文

0 投票
1 回答
3013 浏览

c# - 弱事件如何运作?

我目前正在学习 WPF,并且偶然发现了弱事件的概念,但我真的很难“得到它”。我已经阅读了无数关于 Stackoverflow 的文章并查看了代码示例,但它并没有深入人心。

这是我的困境:

  1. 我知道当一个对象订阅一个事件时,事件的源必须持有对订阅者的引用。
  2. 我也明白,如果订阅者超出范围或被显式销毁但事件源没有被销毁,那么订阅者将不会被垃圾收集,因为事件源仍然保留对订阅者的引用。
  3. 避免这种情况的常用方法是在对象被销毁之前显式取消订阅源的订阅。我知道如果程序员无法确定何时会发生这种情况,这可能是一个问题。

所以从上面我了解了事件的使用如何导致内存泄漏以及为什么需要弱引用模式,但阻止我理解的是弱事件模式实际上是如何实现这个目标的?它有什么不同?

当然,即使有一个管理事件的类,它仍然必须订阅和取消订阅处理程序到/从源,因此引用必须存在,这给使用事件的标准方式带来了同样的问题。

有人请向我解释我缺少或误解的基本概念,并帮助我“了解”弱事件模式。