C# - 试图找到剩余的EventHandler,防止控件超出范围

时间:2011-11-09 18:59:11

标签: c# memory-leaks profiling

长话短说,我继承了一个相当复杂的应用程序,我正在尝试追踪涉及表单的内存泄漏。现在,每次关闭表格并提出新表格时,旧表格都会留在记忆中。我跟踪了一个由程序中的控件拥有和设置的静态事件的问题(显然,只要静态事件被设置,该控件的任何实例都不被认为超出范围,即使没有其他人提到所述控件)。现在,我正在努力追查剩下的问题。

使用MemProfiler和ANTS Memory Profile,我了解到根执行路径是这样的:

FormOpenWatch        <--       The item which remains active
System.EventHandler -- (this as Delegate)._target
System.Object[]
System.EventHandler -- (this as MultiCastDelegate)._invocationList
System.ComponentModel.EventHandlerList+ListEntry  --  handler
System.ComponentModel.EventHandlerList+ListEntry  --  next
System.ComponentModel.EventHandlerList+ListEntry  --  next
System.ComponentModel.EventHandlerList+ListEntry  --  next
System.ComponentModel.EventHandlerList+ListEntry  --  next
System.ComponentModel.EventHandlerList  --  head
PTU.MdiPTU  --  (this as Component).events        <--       The base application

任何人都对我可能想要的东西有任何见解?我发现在基础应用程序中添加了一个Shown事件,并确保在处理表单时将其删除,但这似乎没有解决问题。

非常感谢您提供的任何帮助。

后来的编辑:我以为我已经成功解决了几次这个问题,而且我还有问题。问题似乎源于我的Plotter类(和各种派生类)具有这个“公共静态事件MouseEventHandler MultiCursorMouseMove;”事件。我们有一个“光标”,显示图形在鼠标位置的值和时间。最初,这一次在一个图表上工作,但是请求允许用户切换一种模式,其中移动鼠标将图表移动到所有显示的图形上。当项目被实例化时,我写了一个初始处理程序挂钩EventHandlers,并且我在池塘的伙伴重新编写它以使用静态事件,该事件被分配给构造中的每个项目。他的方式更优雅,更好。除了导致内存泄漏之外的所有内容。使用内存分析软件已经表明,每次我试图摆脱持有图的表格时,我都会留下一些“带有直接EventHandler根的Disposed实例”。在每一个中,它表明该对象是绘图仪或绘图仪指向的对象。并且,在每个中,基本链接是MultiCursorMouseMove EventList指向这些对象。我认为正在发生的事情是绘图仪仍然活着,因为它有这个静态事件,而这个事件又与绘图仪有关。我已经设法通过我的Dispose代码删除每个绘图仪的事件来验证MultiCursorMouseMove在给定点通过调试器是空的,但是在同一点运行探查器仍然显示从MultiCursorMouseMove到这些类的链。

我目前没有关于如何解决这个问题的想法。任何人吗?

1 个答案:

答案 0 :(得分:1)

如果MdiPTU是您的应用程序的MDI父表单,则听起来FormOpenWatch可能已订阅其中一个事件。如果它没有直接完成,您可能会在FormOpenWatch超类中找到订阅,或者甚至可能在其他代码中找到可以从MdiPTU事件中连接FormOpenWatch方法的执行。