将静态/全局事件处理程序绑定到类中的事件,会导致线程/内存泄漏吗?
本文关键字:线程 内存 泄漏 事件 事件处理 全局 静态 程序 绑定 | 更新日期: 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
}
}
因为你的处理程序是静态方法,你添加到事件的委托没有对象实例,所以没有对象实例在对象与事件的持续时间内保持活动。
并且即使您确实使用对象实例来附加处理程序,也不会有问题,因为具有事件的对象是短暂的。唯一出现问题的情况是,具有事件的对象是长期存在的,而为自己分配了处理程序的对象是短期存在的,并且需要消耗大量资源来保持活动。