WeakEvent的事件侦听器可以随时通过垃圾回收删除吗?

我正在寻找一种避免使用事件时发生内存泄漏的解决方案(如果从未从事件源中删除侦听器,则可能会发生这种情况。我发现此code project article描述了一个WeakEvent类,如下所示:

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指向它),所以整个模式变得不确定。如果这是正确的,为什么我仍然应该使用这样的模式?

Thx

weiweisenge 回答:WeakEvent的事件侦听器可以随时通过垃圾回收删除吗?

是的,如果WeakReference是唯一拥有对ListenerObject的引用的东西,那么ListenerObject可以随时进行GC处理。

如果您的EventWrapper类不是唯一引用ListenerObject的东西,而您的EventWrapper没有,则使用这样的模式不知道另一件事何时将释放对ListenerObject的引用。

例如,ListenerObject可能是显示在屏幕上的UI控件,而EventWrapper可能是由单例服务拥有的。只要显示该屏幕,UI控件就会保持活动状态,但是当用户更改屏幕时将被释放。该服务可能不知道何时发生。使用弱事件模式意味着在这种情况下,您不会意外地导致内存泄漏。


请注意,如果您确实想实现弱事件模式,请使用this article中详细介绍的WeakEventManager

本文链接:https://www.f2er.com/2758440.html

大家都在问