Arbeitsspeicher nicht freigegeben, wenn Windows Forms-Anwendung ToolTip.SetToolTip verwendet
Dieser Artikel hilft Ihnen, das Problem zu beheben, bei dem Windows Forms-Anwendung möglicherweise keinen Arbeitsspeicher freigibt, wenn die ToolTip.SetToolTip Methode falsch verwendet wird.
Ursprüngliche Produktversion: .NET Framework 4.5
Ursprüngliche KB-Nummer: 2749543
Problembeschreibung
Sie haben eine .NET Windows Forms-Anwendung entwickelt, die die ToolTip.SetToolTip Methode verwendet, um ein QuickInfo-Steuerelement einem Windows Forms-Steuerelement zuzuordnen. Wenn das zugeordnete Windows Forms-Steuerelement programmgesteuert aus dem Formular entfernt und entfernt wird, wird das Steuerelement nicht vom verwalteten Heap freigegeben. Wenn Steuerelemente, die einer Verwendung zugeordnet sind, wiederholt hinzugefügt und entfernt werden, nimmt die Speicherauslastung im Laufe der Zeit ToolTip weiter zu und kann schließlich zu einem ToolTip.SetToolTip System.OutOfMemoryException .
Ursache
Beim ToolTip.SetToolTip Aufrufen, um ein ToolTip Windows Forms-Steuerelement zuzuordnen, speichert das ToolTip Objekt interne Informationen, einschließlich eines Verweises auf das Steuerelement, in einer internen HashTable. Wenn Sie ein einzelnes QuickInfo-Steuerelement verwenden und es vielen Steuerelementen zuordnen, wird ein Verweis auf jedes Steuerelement und dessen ToolTip Informationen in der HashTable gespeichert. Weder das Aufrufen der Methode eines Steuerelements Dispose noch das Entfernen dieser Methode aus der Auflistung des Controls zugehörigen Containers heben die Zuordnung des Steuerelements zum Steuerelement ToolTip auf. In einem Szenario, in dem die Anwendung einem Formular Dynamisch Steuerelemente hinzufügt, sie einem Formular zufügt ToolTip und entfernt und entfernt. Das Steuerelement ist weiterhin im Arbeitsspeicher verankert, und der verwaltete Speicher-Heap der Anwendung wird im Laufe der Zeit weiter wachsen.
Lösung
Je nach Anwendungsdesign gibt es mehrere Möglichkeiten, dieses Problem zu beheben.
Wenn die Anwendung ein QuickInfo-Steuerelement für viele Windows Forms-Steuerelemente verwendet, können Sie die Zuordnung eines bestimmten Windows Forms-Steuerelements aus der QuickInfo aufheben, indem Sie ToolTip.SetToolTip einen Verweis auf das Steuerelement und eine leere Zeichenfolge für die Beschriftung aufrufen und ToolTip übergeben. Wenn eine leere Zeichenfolge für die ToolTip Beschriftung übergeben wird, entfernt die SetToolTip Methode den Verweis auf das Windows Forms-Steuerelement aus der internen HashTable von ToolTip .
Hinweis
Sie können auch die ToolTip.RemoveAll aufrufen, um den gesamten Text zu entfernen ToolTip und die Zuordnung des QuickInfo-Steuerelements von allen Windows Forms-Steuerelementen zu trennen.
Wenn die Anwendung nicht mehrere Windows Forms-Steuerelemente einer einzelnen QuickInfo zuzuordnen ist, können Sie die Dispose Methode von ToolTip aufrufen.
Weitere Informationen
Es handelt sich hierbei um ein beabsichtigtes Verhalten.
Berücksichtigen Sie den folgenden Beispielcode in einer Windows Forms-Anwendung. Der Code in der CreateControls() Methode erstellt eine Reihe von TextBox-Steuerelementen, ruft ToolTip.SetToolTip auf, jedem Steuerelement eine ToolTip Beschriftung zuzuweisen, und fügt das Steuerelement einem internen ObservableCollection Steuerelement und der Auflistung Controls hinzu. Der Code in der RemoveControls() Methode durchläuft das ObservableCollection Steuerelement, ruft einen Verweis auf jedes Steuerelement ab, entfernt es dann aus der ObservableCollection Sammlung des Formulars und ruft dann dessen Controls Methode Dispose auf. Dies führt dazu, dass jedes der TextBox-Steuerelemente aus dem Formular entfernt und verworfen wird, aber die Instanz jedes TextBox-Steuerelements und jedes ToolTipInfo zugehörigen Steuerelements ist weiterhin im verwalteten Heap verankert. Wenn Sie die Auskommentierung der angegebenen Zeile in der RemoveControls() Methode aufheben, wird die Zuordnung des TextBox-Steuerelements vom TextBox-Objekt aufgehoben ToolTip und die Garbage Collection ermöglicht.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.ObjectModel;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
ObservableCollection<TextBox> list;
ToolTip toolTip;
public Form1()
{
InitializeComponent();
toolTip = new ToolTip();
list = new ObservableCollection<TextBox>();
}
private void button1_Click(object sender, EventArgs e)
{
CreateControls();
}
private void button2_Click(object sender, EventArgs e)
{
RemoveControls();
}
private void CreateControls()
{
for (int i = 0; i < 100; i++)
{
TextBox t = new TextBox();
toolTip.SetToolTip(t, i.ToString());
t.Left = (t.Width * i) + 5;
list.Add(t);
this.Controls.Add(t);
}
}
private void RemoveControls()
{
for (int i = list.Count-1;i>=0;i--)
{
TextBox tb = list[i];
this.Controls.Remove(tb);
list.Remove(tb);
//Uncomment this line to disassociate the ToolTip control from the Windows Forms Control
//toolTip.SetToolTip(tb, "");
tb.Dispose();
}
}
}
}