Разработчики знают, что использование управления WinForms ToolStrip может привести к утечке управляемой памяти, если мы не заставим его вручную отпустить некоторые вещи. Я имею в виду внутренний обработчик событий системы static Microsoft.Win32.SystemEvents.UserPreferenceChanged
. Чтобы правильно освободить ресурсы, нам нужен явный вызов метода ToolStrip Dispose, как описано, например, в this или this SO сообщения.ToolStrip.Dispose() не помогает избежать утечки памяти в System.ComponentModel.Component
Однако это не поможет, если мы используем ToolStrip от потомка System.ComponentModel.Component - по крайней мере, в моем случае. Вот соответствующая часть кода:
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), поскольку обработчик события UserPreferenceChanged должен быть удален ToolStrip автоматически в этом случае. Да, при этом вызывается внутренний метод 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+ (профиль клиента).