长话短说,我继承了一个相当复杂的应用程序,我正试图追踪涉及表单的内存泄漏。现在,每次关闭表单并调出新表单时,旧表单都会保留在内存中。我追踪了一个由程序中的控件拥有和设置的静态事件的问题(显然,只要设置了静态事件,该控件的任何实例都不会被视为超出范围,即使没有其他人引用所述控件).现在,我正在尝试追查剩余的问题。
使用 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 类(和各种派生类)具有此“公共(public)静态事件 MouseEventHandler MultiCursorMouseMove;”事件。我们有一个“光标”,它在鼠标所在的位置显示图形的值和时间。最初,这一次只在一个图表上工作,但提出了一个请求,允许用户切换一种模式,在该模式下,移动鼠标会在所有显示的图表上移动绘图。我编写了一个初始处理程序,在实例化项目时将 EventHandlers Hook ,而我在池塘对面的合作伙伴重写了它以使用静态事件,该事件被分配给构建时的每个项目。他的方式更优雅,效果更好。所有除了它导致内存泄漏。使用内存分析软件表明,每次我试图摆脱持有情节的形式时,我都会遇到许多“具有直接 EventHandler 根的处置实例”的情况。在其中的每一个中,它都表明该对象是绘图仪,或者是绘图仪指向的对象。并且,在每一个中,基本链接是 MultiCursorMouseMove EventList 指向这些对象。我认为正在发生的事情是绘图仪保持事件状态,因为它有这个静态事件,而这个静态事件又与绘图仪相关联。由于我的 Dispose 代码删除了每个绘图仪的事件,我已经设法在给定点通过调试器验证 MultiCursorMouseMove 是否为空,但在同一点运行探查器仍然显示从 MultiCursorMouseMove 到这些类的链。
我目前不知道如何解决这个问题。有人吗?
最佳答案
如果 MdiPTU 是您应用程序的 MDI 父窗体,听起来 FormOpenWatch 可能已经订阅了它的事件之一。如果它没有直接这样做,您可能会在 FormOpenWatch 父类(super class)中找到订阅,或者甚至可能在其他代码中可以从 MdiPTU 事件连接执行 FormOpenWatch 方法。
关于C# - 试图找到剩余的 EventHandler 以防止控制超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8070094/