La memoria no se libera si Windows forms usa ToolTip.SetToolTip

Este artículo le ayuda a resolver el problema en el que Windows forms puede que no libere memoria si usa ToolTip.SetToolTip el método incorrectamente.

Versión del producto original:   .NET Framework 4.5
Número KB original:   2749543

Síntomas

Ha desarrollado una aplicación de .NET Windows Forms, que usa el método para asociar un control ToolTip con un control Windows ToolTip.SetToolTip Forms. Al quitar mediante programación el control Windows Forms asociado del formulario y eliminarlo, el control no se libera del montón administrado. Con el tiempo, si se agregan y quitan repetidamente controles asociados a un uso , el uso de memoria continúa aumentando y puede resultar ToolTip ToolTip.SetToolTip en un System.OutOfMemoryException .

Causa

Al llamar para asociar un control Windows Forms, el objeto almacena información interna, incluida una referencia al control, dentro de ToolTip.SetToolTip ToolTip un ToolTip hashTable interno. Si usa un único control de información sobre herramientas y lo asocia con muchos controles, se almacena una referencia a cada control y su información dentro ToolTip de HashTable. Ni llamar al método de un control ni quitarlo de la colección de Dispose Controls su contenedor desasocia el control de su ToolTip . Por lo tanto, en un escenario en el que la aplicación agrega controles dinámicamente a un formulario, asociándolos con un , y quitándolos y desechándolos; el control todavía está enraizado en la memoria y el montón de memoria administrada de la aplicación seguirá creciendo con el ToolTip tiempo.

Solución

Según el diseño de la aplicación, hay varias formas de resolver este problema.

Si la aplicación usa un control De información sobre herramientas para muchos controles de formularios de Windows, puede desasociar un determinado control de formularios de Windows de la información sobre herramientas llamando y pasando una referencia al control y una cadena vacía para el ToolTip.SetToolTip ToolTip título. Cuando se pasa una cadena vacía para el título, el método quita la referencia al control Windows Forms desde dentro de ToolTip SetToolTip la HashTable interna de ToolTip .

Nota

También puede llamar al para quitar todo el texto ToolTip.RemoveAll ToolTip y desasociar el control ToolTip de todos los Windows Forms.

Si la aplicación no está asociando varios controles Windows Forms con una sola información sobre herramientas, puede llamar al Dispose método ToolTip de .

Más información

Este comportamiento es una característica del diseño de la aplicación.

Tenga en cuenta el siguiente código de ejemplo en una Windows Forms. El código del método crea una serie de controles TextBox, llama para asignar un título a cada control y agrega el control a un CreateControls() control interno y a la ToolTip.SetToolTip ToolTip ObservableCollection Controls colección. El código del método recorre , obtiene una referencia a cada control y, a continuación, lo quita de la colección Form y, a continuación, llama RemoveControls() a su ObservableCollection ObservableCollection Controls Dispose método. Da como resultado que cada uno de los controles TextBox se quita del formulario y se elimina, pero la instancia de cada TextBox y asociados todavía están enraizadas en el montón ToolTipInfo administrado. Descommentar la línea especificada en el método desasocia el TextBox de la y permite que sea RemoveControls() ToolTip recolección de elementos no utilizados.

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