开发人员知道,如果我们不强制它手动释放一些东西,WinForms ToolStrip 控件的使用可能会导致托管内存泄漏。我的意思是系统静态事件的内部事件处理程序Microsoft.Win32.SystemEvents.UserPreferenceChanged
。为了正确释放资源,我们需要显式调用 ToolStrip Dispose 方法,例如在此或此SO 帖子中描述的那样。
但是,如果我们使用 System.ComponentModel.Component 的后代的 ToolStrip,这将无济于事——至少在我的情况下是这样。这是代码的相应部分:
Private Class DropDownFilterBox
Inherits System.ComponentModel.Component
Private WithEvents fToolStripMain As New AutoFilterToolStrip
Private WithEvents fToolStripOKCancel As New AutoFilterToolStrip
Private WithEvents fContextMenuStripCustomFilterOperators As New ContextMenuStrip
Private WithEvents fToolStripDropDownCustomFilterDatePicker As New ToolStripDropDown
Private WithEvents fToolStripControlHostCustomFilterDatePicker As New AutoFilterToolStripControlHostDatePicker
.......................
Public Overloads Sub Dispose()
fToolStripMain.Dispose()
fToolStripOKCancel.Dispose()
fContextMenuStripCustomFilterOperators.Dispose()
fToolStripDropDownCustomFilterDatePicker.Dispose()
fToolStripControlHostCustomFilterDatePicker.Dispose()
MyBase.Dispose()
End Sub
End Class
AutoFilterToolStrip 的定义如下:
Private Class AutoFilterToolStrip
Inherits ToolStrip
......................
End Class
,但这在我们的上下文中应该无关紧要。
我什至在需要时手动调用 DropDownFilterBox.Dispose 来清理使用过的资源,但这似乎没有任何效果。
一些开发人员建议隐藏 ToolStrips(将 Visible 属性设置为 False),因为在这种情况下 ToolStrip 应自动删除 UserPreferenceChanged 事件处理程序。是的,应该完成工作的内部 HookStaticEvents 方法被调用。但这也无济于事。
我什至尝试使用反射手动分离问题事件处理程序:
RemoveHandler Microsoft.Win32.SystemEvents.UserPreferenceChanged, _
DirectCast( _
System.Delegate.CreateDelegate(GetType(Microsoft.Win32.UserPreferenceChangedEventHandler), fToolStripMain, "OnUserPreferenceChanged"), _
Microsoft.Win32.UserPreferenceChangedEventHandler _
)
,但这也没有任何效果。
关于如何在我们的案例中克服这个内存泄漏问题以及为什么 ToolStrip.Dispose 的显式调用在我们的案例中可能不起作用的任何想法?
我们在 VB.NET 2010 中为 .NET Framework 4+(客户端配置文件)进行开发。