WeakEvent 的事件监听器是否可以随时被垃圾回收删除?
Can event listener of WeakEvent be deleted by garbage collection any time?
我正在寻找一种解决方案,避免在使用事件时发生内存泄漏(如果从未从事件源中删除侦听器,则可能会发生这种情况。我发现这个 code project article 描述了一个 WeakEvent
class 像这样:
sealed class EventWrapper
{
SourceObject eventSource;
WeakReference wr;
public EventWrapper(SourceObject eventSource,
ListenerObject obj) {
this.eventSource = eventSource;
this.wr = new WeakReference(obj);
eventSource.Event += OnEvent;
}
void OnEvent(object sender, EventArgs e)
{
ListenerObject obj = (ListenerObject)wr.Target;
if (obj != null)
obj.OnEvent(sender, e);
else
Deregister();
}
public void Deregister()
{
eventSource.Event -= OnEvent;
}
}
据我所知,侦听器对象包装在 WeakReference
中,从垃圾收集器的角度来看,这不被视为对事件侦听器的引用。
我的问题:使用此模式时,垃圾收集器是否有可能删除 ListenerObject obj
尽管事件源事先没有触发任何事件?在那种情况下,整个模式变得不确定,因为触发的事件没有转发到 ListenerObject
,因为垃圾收集器删除了它(因为只有 WeakReference
指向它)。如果这是正确的,我为什么还要使用这样的模式?
感谢
是的,如果 WeakReference
是唯一引用 ListenerObject
的东西,那么 ListenerObject
可以随时被 GC。
如果您的 EventWrapper
class 是 而不是 唯一引用 ListenerObject
的内容,您将使用这样的模式,但是你的 EventWrapper
不知道其他东西什么时候会释放它对 ListenerObject
.
的引用
例如,ListenerObject
可能是出现在屏幕上的 UI 控件,而 EventWrapper
可能属于单例服务。只要该屏幕显示,UI 控件就会保持活动状态,但会在用户更改屏幕时释放。该服务可能不知道何时发生。使用弱事件模式意味着在这种情况下您不会意外地导致内存泄漏。
请注意,如果您确实想要实施弱事件模式,请使用 this article 中详述的 WeakEventManager
。
我正在寻找一种解决方案,避免在使用事件时发生内存泄漏(如果从未从事件源中删除侦听器,则可能会发生这种情况。我发现这个 code project article 描述了一个 WeakEvent
class 像这样:
sealed class EventWrapper
{
SourceObject eventSource;
WeakReference wr;
public EventWrapper(SourceObject eventSource,
ListenerObject obj) {
this.eventSource = eventSource;
this.wr = new WeakReference(obj);
eventSource.Event += OnEvent;
}
void OnEvent(object sender, EventArgs e)
{
ListenerObject obj = (ListenerObject)wr.Target;
if (obj != null)
obj.OnEvent(sender, e);
else
Deregister();
}
public void Deregister()
{
eventSource.Event -= OnEvent;
}
}
据我所知,侦听器对象包装在 WeakReference
中,从垃圾收集器的角度来看,这不被视为对事件侦听器的引用。
我的问题:使用此模式时,垃圾收集器是否有可能删除 ListenerObject obj
尽管事件源事先没有触发任何事件?在那种情况下,整个模式变得不确定,因为触发的事件没有转发到 ListenerObject
,因为垃圾收集器删除了它(因为只有 WeakReference
指向它)。如果这是正确的,我为什么还要使用这样的模式?
感谢
是的,如果 WeakReference
是唯一引用 ListenerObject
的东西,那么 ListenerObject
可以随时被 GC。
如果您的 EventWrapper
class 是 而不是 唯一引用 ListenerObject
的内容,您将使用这样的模式,但是你的 EventWrapper
不知道其他东西什么时候会释放它对 ListenerObject
.
例如,ListenerObject
可能是出现在屏幕上的 UI 控件,而 EventWrapper
可能属于单例服务。只要该屏幕显示,UI 控件就会保持活动状态,但会在用户更改屏幕时释放。该服务可能不知道何时发生。使用弱事件模式意味着在这种情况下您不会意外地导致内存泄漏。
请注意,如果您确实想要实施弱事件模式,请使用 this article 中详述的 WeakEventManager
。