2009-12-08 9 views
3

J'ai eu des problèmes avec des fuites de mémoire avec le SWF-ToolStrip. Selon ce http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115600# a été résolu. Mais ici, il semble que non.Fuite de mémoire ToolStrip

Quelqu'un sait comment résoudre ce problème?

+0

Quelle version du framework .NET a été résolu dans? Utilisez-vous cette version? –

+0

J'utilise le dernier framework .Net. 3.5. Mais nous avons décidé de supprimer la barre d'outils et d'implémenter la fonction avec d'autres contrôles pour contourner le problème de la mémoire. –

Répondre

1

Ceci est une plainte remarquablement persistante. La source de la fuite était ToolStrip en installant un gestionnaire d'événement pour l'événement SystemEvents.UserPreferenceChanged. Afin qu'il puisse répondre à l'utilisateur en changeant le thème ou le schéma de couleurs et se redessiner. C'est un événement statique, oublier de désenregistrer le gestionnaire d'événements provoquera une fuite permanente de l'instance ToolStrip.

Le bogue a définitivement été corrigé dans .NET 3.5 SP1. La méthode ToolStrip.Dispose() annule l'inscription du gestionnaire d'événements. Si c'est la version que vous exécutez, assurez-vous que la méthode Dispose() s'exécute bien. Une erreur courante consiste à utiliser Controls.Remove() pour supprimer un contrôle d'un formulaire, puis oublier d'appeler Dispose() sur le contrôle supprimé.

1

Private Sub frmBase_FormClosed (sender ByVal comme objet, ByVal e comme System.Windows.Forms.FormClosedEventArgs) Poignées 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

Ce problème semble persister dans .NET 3.5 SP1 ainsi que .NET 4.0.

Pour reproduire le problème, vous devez créer un ToolStrip avec plus d'éléments qu'il ne peut afficher, ce qui entraîne la création d'un bouton de débordement. Le problème n'apparaît que lorsque vous cliquez sur le bouton de débordement. En cliquant dessus, vous créez un objet ToolStripOverflow qui s'abonne à l'événement Microsoft.Win32.UserPreferenceChangedEventHandler. ToolStrip ne dispose pas de l'objet ToolStripOverflow qui empêche le gestionnaire d'événements d'être supprimé et provoque une fuite.

Cela nous a causé d'énormes problèmes dans une grande application qui a créé des formulaires avec ToolStrips sur eux.

Un travail autour de changer la méthode Dispose de la forme ou de contrôle qui héberge ToolStrip comme suit:

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

Cette résolu le problème pour nous