将静态/全局事件处理程序绑定到类中的事件,会导致线程/内存泄漏吗?

本文关键字:线程 内存 泄漏 事件 事件处理 全局 静态 程序 绑定 | 更新日期: 2023-09-27 18:05:15

我在构造函数中有一个带有EventHandler绑定的类,它将在应用程序生命周期中实例化数千次。问题是:这种方法会导致内存/线程泄漏吗?

我这样做了(下面的代码),因为每次SomeMethod()运行时我都需要得到通知,无论运行它的实例是什么。Foo类(发布者)将是短暂的,但是处理程序将一直存在到应用程序关闭。

我问这个问题是因为,当使用Windows窗体时,每个窗体可以容纳几个事件处理程序/委托,一切都很好,因为所有这些委托都在窗体内,并将在窗体关闭时被处理掉。但是,静态事件处理程序/委托如何,甚至可以在单独的项目?

我需要写一个析构函数来分离这些事件处理程序吗?我应该使用弱事件模式吗?

限制:我必须在。net 3.5中这样做。我知道我可以在TPL中做到这一点,设置一个"立即删除"任务。

提前谢谢你。

代码:

public class Foo
{
    public event EventHandler SomeEvent;
    public Foo()
    {
        SomeEvent += FooHandlers.Foo_SomeEvent1;
        SomeEvent += FooHandlers.Foo_SomeEvent2;
    }
    public void RaiseEvents(EventHandler evt, EventArgs args)
    {
        var eventObj = evt; 
        var listeners = eventObj.GetInvocationList();
        foreach (var listener in listeners)
        {
            var method = (EventHandler)listener;
            ThreadPool.QueueUserWorkItem(callBack => method(this, args));
            // Handlers will do a lot of things, so I don't want
            // them blocking the Main thread
        }
    }
    public void SomeMethod()
    {
        // do something here
        RaiseEvents(SomeEvent, new EventArgs());
    }
}
public static class FooHandlers
{
    public static void Foo_SomeEvent1(object sender, EventArgs e)
    {
        //do something here
    }
    public static void Foo_SomeEvent2(object sender, EventArgs e)
    {
        //do something different here
    }
}

将静态/全局事件处理程序绑定到类中的事件,会导致线程/内存泄漏吗?

因为你的处理程序是静态方法,你添加到事件的委托没有对象实例,所以没有对象实例在对象与事件的持续时间内保持活动。

并且即使您确实使用对象实例来附加处理程序,也不会有问题,因为具有事件的对象是短暂的。唯一出现问题的情况是,具有事件的对象是长期存在的,而为自己分配了处理程序的对象是短期存在的,并且需要消耗大量资源来保持活动。