Les développeurs savent que l'utilisation du contrôle WinForms ToolStrip peut entraîner des fuites de mémoire gérée si nous ne le forçons pas à libérer des éléments manuellement. Je veux dire le gestionnaire d'événement interne de l'événement Microsoft.Win32.SystemEvents.UserPreferenceChanged
statique du système. Pour libérer les ressources correctement, nous avons besoin d'un appel explicite de la méthode ToolStrip Dispose tel qu'il est décrit, par exemple, dans les publications SO this ou this. Cependant, cela n'aide pas si nous utilisons un ToolStrip d'un descendant de System.ComponentModel.Component - au moins, dans mon cas. Voici la partie correspondante du code:ToolStrip.Dispose() ne permet pas d'éviter les fuites de mémoire dans 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
Le AutoFilterToolStrip est défini comme ceci:
Private Class AutoFilterToolStrip
Inherits ToolStrip
......................
End Class
, mais cela ne devrait pas d'importance dans notre contexte.
J'appelle même DropDownFilterBox.Dispose manuellement pour nettoyer les ressources utilisées quand c'est nécessaire, mais il semble que cela n'a aucun effet.
Certains développeurs recommandent de masquer ToolStrips (définissez la propriété Visible sur False) car le gestionnaire d'événements UserPreferenceChanged doit être supprimé automatiquement par ToolStrip dans ce cas. Oui, la méthode interne HookStaticEvents qui devrait faire le travail est appelée à cela. mais cela n'aide pas non plus.
J'ai même essayé de détacher le gestionnaire d'événements problème manuellement à l'aide de réflexion:
RemoveHandler Microsoft.Win32.SystemEvents.UserPreferenceChanged, _
DirectCast(_
System.Delegate.CreateDelegate(GetType(Microsoft.Win32.UserPreferenceChangedEventHandler), fToolStripMain, "OnUserPreferenceChanged"), _
Microsoft.Win32.UserPreferenceChangedEventHandler _
)
, mais cela ne aussi aucun effet.
Des idées sur la façon de surmonter ce problème de fuite de mémoire dans notre cas et pourquoi l'appel explicite de ToolStrip.Dispose peut ne pas fonctionner dans notre cas?
Nous développons dans VB.NET 2010 pour .NET Framework 4+ (profil client).