2009-12-08 1 views
3

У меня возникли проблемы с утечками памяти с помощью SWF-ToolStrip. В соответствии с этим http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115600# был разрешен. Но здесь, похоже, нет.Утечка памяти ToolStrip

Кто-нибудь знает, как это решить?

+0

Какая версия платформы .NET была она решена в? Вы используете эту версию? –

+0

Я использую новейшую инфраструктуру .Net. 3.5. Но мы решили удалить панель инструментов и реализовать функцию с другими элементами управления, чтобы обойти память. – 2009-12-08 14:11:42

ответ

1

Это замечательная настойчивая жалоба. Источником утечки был ToolStrip, устанавливающий обработчик событий для события SystemEvents.UserPreferenceChanged. Чтобы он мог реагировать на пользователя, изменяя тему или цветовую схему и перерисовывая себя. Это статическое событие, забывающее отменить регистрацию обработчика событий, который будет постоянно терять экземпляр ToolStrip.

Исправлена ​​ошибка в .NET 3.5 SP1. Метод ToolStrip.Dispose() отменяет регистрацию обработчика события. Если это версия, которую вы используете, убедитесь, что метод Dispose() действительно работает. Общей ошибкой является использование Controls.Remove(), чтобы удалить элемент управления из формы, но затем забыть вызвать Dispose() на удаленном элементе управления.

1

Private Sub frmBase_FormClosed (ByVal отправитель As Object, ByVal е Как 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 
3

Эта проблема, как представляется, сохранится в .NET 3.5 SP1, а также .NET 4.0.

Чтобы воспроизвести проблему, вы должны создать ToolStrip с большим количеством элементов, чем может отображать, что заставляет его создавать кнопку переполнения. Проблема возникает только при нажатии кнопки переполнения. При нажатии этого объекта создается объект ToolStripOverflow, который подписывается на событие Microsoft.Win32.UserPreferenceChangedEventHandler. Инструмент ToolStrip не удаляет объект ToolStripOverflow, который не позволяет удалить обработчик события и вызывает утечку.

Это вызвало массовые проблемы в большом приложении, которое создало формы с помощью ToolStrips.

Произведение вокруг изменить метод Dispose формы или элемента управления, на котором размещена ToolStrip следующим образом:

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

Это решило его для нас