问题标签 [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 投票
1 回答
288 浏览

c# - 来自 Reactive 扩展的 PCL WeakEventManager 在 3 - 7 分钟内处理事件

我正在尝试使用 Reactive 库在 PCL 中实现 WeakEventManager。

所以关键是它为订阅者保留一个弱引用,并且每次事件触发时 - 它获取订阅者的委托并触发它,但如果他无法从弱引用中获取对象,那么它会将链接释放到代表。

问题是,在很短的时间之后,弱引用返回 null (但订阅者仍然活着),然后正在执行链接的处置。所以我的问题是为什么会发生这种情况以及如何解决这个问题?

这里的样子:(看代码中的注释)

然后这是我使用该管理器订阅的方式:

还有我的活动发布者:

最后是 WeakEventManager 类的完整代码:

0 投票
3 回答
4198 浏览

c# - 将所有标准事件处理程序替换为 WeakEventManager 或其变体是否安全?

标准事件处理程序(使用 operator +=)是内存泄漏原因之一(如果它不是未注册/处置(使用-=operator))。

WeakEventManager微软用它的继承解决了它,比如:PropertyChangedEventManager, CollectionChangedEventManager, CurrentChangedEventManager, ErrorsChangedEventManager等等。

内存泄漏的简单示例代码是:

输出是:

我们可以看到析构函数不会被调用。但是如果我们改变(通过注释未使用的代码):

输出是:

在 A 为空之后,它的事件处理程序将不再被调用。A 和 B 将在没有操作员的情况下不再使用后被处理掉-=

  1. 我可以安全地替换所有 += 运算符,System.Windows.WeakEventManager以避免由于可能缺少事件注销和保存代码而导致的内存泄漏,应该不实现IDisposable

  2. 如果它不是真的安全,我应该考虑或注意什么?

0 投票
0 回答
58 浏览

c# - GC和弱事件

我很惊讶无法找到有关该主题的任何内容。

垃圾收集不是确定性的(它会在以后发生)。这是否意味着弱事件处理程序可能(将?)继续为未引用的对象调用?这可能是问题的原因(性能、处置的对象状态等),对吧?

GC.Collect()如果我必须使用弱事件,那么显式调用以避免此类问题是一个好主意(是否足够?) ?

PS:我有一些软件的性能问题,并试图在尝试更耗时的事情之前填补我的知识空白。

0 投票
1 回答
926 浏览

c# - WeakEventManager - 不调用事件处理程序

我无法重现该问题(并且项目太大而无法在此处发布,而且我不确定要发布哪些相关部分)并且我需要了解此处可能出现的问题。

我有带有静态事件的抽象类

然后我正常订阅此事件并使用WeakEventManager

并且由于某些原因,弱事件处理程序在被调用时不会被触发OnTest()。一切(调用和处理程序)都在 UI 线程中运行。

我设置了断点:

  1. 在 上AddHandler(),它运行,然后类的实例持续存在。
  2. On Invoke(),它在OnTest被调用时运行,如果我调用Test.GetInvocationList()其中一个是DeliverEvent()from ,我可以看到 2 个订阅者WeakEventManager,因此事件已注册并且Invoke()应该调用弱事件处理程序。
  3. 在普通事件处理程序中,它运行。
  4. 在弱事件处理程序中,什么都没有,这个断点永远不会被击中。

关于为什么会发生这种情况或我应该调查什么的任何想法?


我试图查看 .net资源,在那里找到答案,但有些ProtectedAddHandler资源我找不到……我找到,但接下来是什么?抽象方法,谁来实现?...

0 投票
1 回答
204 浏览

wpf - Microsoft.Win32.SystemEvents 事件不适用于 WeakEventManager

当我做

OnDisplaySettingsChanged永远不会被调用。但是,如果我改为使用正常的事件订阅,SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged一切正常。

这是怎么回事?

0 投票
0 回答
178 浏览

wpf - WPF 弱订阅 IsEnabledChanged 事件

是否可以订阅UIElement.IsEnabledChanged事件?

既不是WeakEventManager<TEventSource, TEventArgs>

似乎有效,因为DependencyPropertyChangedEventArgs不扩展TEventArgs
也不是PropertyChangedEventManager

确实有效,因为UIElement没有实施INotifyPropertyChanged!人们应该如何安全地订阅该事件?

0 投票
1 回答
143 浏览

c# - 是否可以为 UIElement.LayoutUpdated 实现 WeakEventManager?

我有一个使用 LayoutUpdated-events 并需要注册它们的应用程序。这是问题,我在执行 WeakEventManager 期间遇到了问题

这就是发生的事情:

  1. 我们总是收到 null 作为发件人(根据 LayoutUpdated 的设计)
  2. 该 null 被传递到 DeliverEvent
  3. DeliverEvent 无法查找正确的 ListenerList,因为它需要一个 sender != null 作为键

WPF中的失败查找:WeakEventManager // DeliverEvent // 行:359

我的问题是:有没有办法弱注册到 LayoutUpdated 事件?

我对 sender-parameter 不感兴趣,所以 LayoutUpdated 总是提供 null 对我来说是可以的(我使用常规“+=”的实际实现有效)。但是 WeakEventManager 基类依赖 sender-parameter 来跟踪 ListenerList。

0 投票
0 回答
17 浏览

c# - 弱事件模式对源和侦听器都很弱吗?

阅读有关弱事件模式的信息对我来说很清楚,它允许在listener不再引用它时进行垃圾收集,但倒数也是如此吗?意思是这种模式是否允许在source不再引用它时进行垃圾收集(除了通过附加的 weak listener)?

我为什么要问这个:我想在一些“源”和“监听器”之间实现一个 CopyOnWrite 模式,其中第二个只是第一个的子集。因此,每当写入源/侦听器或源消失时,我都需要“分离”(因为无需保留大量数据,而仅引用了一个子集)。因此,我需要在源和侦听器之间进行非常松散的耦合(即,只要不再强烈引用其中一个或另一个,就让它们都被垃圾收集)。

0 投票
0 回答
38 浏览

c# - C# 对 FileSystemWatcher.Created 事件使用弱事件

我正在尝试制作一个程序来监视文件夹中的文件创建事件并对文件进行一些处理。我当前的实现使用:

但是,这似乎有内存泄漏。每次FileSystemWatcher_Created调用时,垃圾收集器在完成时不会处理它。我认为当原始对象仍然存在时,每个实例FileSystemWatcher_Created都不能被处理掉。FileSystemWatcher

在这种情况下,我认为 using 对我没有fileSystemWatcher.Created -= FileSystemWatcher_Created;帮助,因为我不想FileSystemWatcher_Created只运行一次。我想FileSystemWatcher_Created在每次文件创建事件发生时运行。我只希望垃圾收集器正确处理每个实例用完的内存。

我认为这意味着我想使用 aWeakEventHandler来处理事件对吗?在这种情况下我该怎么做?我正在使用.NET Core,但仍会感谢任何.NET Framework答案。

编辑添加:FileSystemWatcher_Created。我在检测到的文件上运行 PowerShell 脚本,然后在处理后移动它。

经过一些试验和错误后,通过使用匿名函数订阅事件,我得到的内存泄漏最少。

0 投票
0 回答
17 浏览

.net - .NET 框架引擎出现异常时如何处理?

由于未知原因,.NET 框架生成了一个内部异常,这使得任何调试过程都无法进行。即使我在 Visual Studio 下以调试模式运行程序,崩溃也是残酷的,没有任何可能看到调用堆栈。完整跟踪:

在这种情况下如何进行?