ToolStrip memory leak

拥有回忆 提交于 2019-12-01 05:15:04

问题


I've been having trouble with memory leaks with the SWF-ToolStrip. According to this http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115600# is has been resolved. But here it seemes not.

Anyone know how to resolve this?


回答1:


This problem seems to persist in .NET 3.5 SP1 as well as .NET 4.0.

To reproduce the problem you must create a ToolStrip with more items than it can display which causes it to create an overflow button. The problem only appears when you actually click the overflow button. Clicking it causes a ToolStripOverflow object to be created which subscribes to the Microsoft.Win32.UserPreferenceChangedEventHandler event. The ToolStrip doesn't dispose of the ToolStripOverflow object which causes the event handler to not be removed and causes a leak.

This caused us massive problems in a large app that created forms with ToolStrips on them.

A work around is to change the Dispose method of the form or control that hosts the ToolStrip as follows:

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);
}

This solved it for us




回答2:


This is a remarkably persistent complaint. The source of the leak was ToolStrip installing an event handler for the SystemEvents.UserPreferenceChanged event. So that it can respond to the user changing the theme or color scheme and redraw itself. This is a static event, forgetting to unregister the event handler will permanently leak the ToolStrip instance.

The bug has definitely been fixed in .NET 3.5 SP1. The ToolStrip.Dispose() method unregisters the event handler. If that's the version you are running, make sure that the Dispose() method indeed runs. A common mistake is to use Controls.Remove() to remove a control from a form but then forgetting to call Dispose() on the removed control.




回答3:


Private Sub frmBase_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles 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


来源:https://stackoverflow.com/questions/1865741/toolstrip-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!