ToolStrip内存泄漏

我一直在使用SWF-ToolStrip解决内存泄漏问题。 根据这个http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115600#已经解决了。 但这里看起来并非如此。

有谁知道如何解决这个问题?

这个问题似乎在.NET 3.5 SP1和.NET 4.0中仍然存在。

要重现该问题,您必须创建一个ToolStrip,其中包含的项目数量超出了可以显示的项目,这会导致它创建溢出按钮。 只有在实际单击溢出按钮时才会出现此问题。 单击它会导致创建ToolStripOverflow对象,该对象订阅Microsoft.Win32.UserPreferenceChangedEventHandler事件。 ToolStrip不会丢弃ToolStripOverflow对象,导致事件处理程序不被删除并导致泄漏。

这导致我们在一个大型应用程序中出现大量问题,这些应用程序使用ToolStrips创建表单。

解决方法是更改​​承载ToolStrip的表单或控件的Dispose方法,如下所示:

protected override void Dispose(bool disposing) { if (disposing) { var overflow = toolStrip1.OverflowButton.DropDown as ToolStripOverflow; if (overflow != null) overflow.Dispose(); } if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } 

这为我们解决了

这是一个非常持久的抱怨。 泄漏源是ToolStrip为SystemEvents.UserPreferenceChanged事件安装事件处理程序。 这样它就可以响应用户更改主题或配色方案并重绘自身。 这是一个静态事件,忘记取消注册事件处理程序将永久泄漏ToolStrip实例。

该错误已在.NET 3.5 SP1中得到修复。 ToolStrip.Dispose()方法取消注册事件处理程序。 如果这是您正在运行的版本,请确保Dispose()方法确实运行。 一个常见的错误是使用Controls.Remove()从表单中删除控件,但后来忘记在删除的控件上调用Dispose()。

Private Sub frmBase_FormClosed(ByVal sender As Object,ByVal e As System.Windows.Forms.FormClosedEventArgs)处理Me.FormClosed

  ' .NET BUG WORKAROUND ' MANUALLY DISPOSE OF ToolStip, MenuStrip and StatusStrip to release memory being held Dim aNames As New ArrayList Dim count As Integer = 0 For Each oItem As ToolStripItem In Me.MenuStrip1.Items aNames.Add(oItem.Name) Next For i As Integer = 0 To aNames.Count - 1 For Each oItem As ToolStripItem In Me.MenuStrip1.Items If oItem.Name = aNames(i) Then oItem.Dispose() Exit For End If Next Next count = 0 aNames.Clear() For Each oItem As ToolStripItem In Me.ToolStrip1.Items aNames.Add(oItem.Name) Next For i As Integer = 0 To aNames.Count - 1 For Each oItem As ToolStripItem In Me.ToolStrip1.Items If oItem.Name = aNames(i) Then oItem.Dispose() Exit For End If Next Next count = 0 aNames.Clear() For Each oItem As ToolStripItem In Me.StatusStrip1.Items aNames.Add(oItem.Name) Next For i As Integer = 0 To aNames.Count - 1 For Each oItem As ToolStripItem In Me.StatusStrip1.Items If oItem.Name = aNames(i) Then oItem.Dispose() Exit For End If Next Next Me.MenuStrip1.Dispose() Me.ToolStrip1.Dispose() Me.StatusStrip1.Dispose() End Sub