相关文章推荐
精明的核桃  ·  dotnet add reference ...·  2 周前    · 
霸气的小虾米  ·  【无人机学习笔记 ...·  9 月前    · 
骑白马的足球  ·  在 Windows 8、Windows ...·  1 年前    · 
聪明伶俐的芒果  ·  docker - Alpine ...·  1 年前    · 
高兴的太阳  ·  JToken,JObject取值_jtoke ...·  1 年前    · 

本文可帮助你解决以下问题:如果错误地使用 ToolTip.SetToolTip 方法,Windows 窗体应用程序可能无法释放内存。

原始产品版本: .NET Framework 4.5
原始 KB 编号: 2749543

你开发了一个 .NET Windows 窗体 应用程序,该应用程序使用 ToolTip.SetToolTip 方法将工具提示控件与Windows 窗体控件相关联。 以编程方式从窗体中删除关联的 Windows 窗体 控件并对其进行释放时,不会从托管堆释放控件。 随着时间的推移,如果反复添加和删除与 使用 ToolTip.SetToolTip 关联的 ToolTip 控件,内存使用量将继续增加,最终 System.OutOfMemoryException 可能会导致 。

调用 ToolTip.SetToolTip 以将 与 Windows 窗体 控件相关联 ToolTip 时,对象会将 ToolTip 内部信息(包括对控件的引用)存储在内部 HashTable 中。 如果使用单个工具提示控件并将其与多个控件相关联,则对每个控件及其 ToolTip 信息的引用存储在 HashTable 中。 调用控件的 Dispose 方法或从 Controls 其容器集合中删除它都不会取消控件与其 ToolTip 的关联。 因此,在应用程序将控件动态添加到窗体、将其与 ToolTip 关联并删除和释放控件的方案中;控件仍扎根于内存中,并且应用程序的托管内存堆将随着时间的推移而继续增长。

根据应用程序设计,有几种方法可以解决此问题。

如果应用程序对许多Windows 窗体控件使用一个工具提示控件,则可以通过调用 ToolTip.SetToolTip 并传递对控件的引用和标题的 ToolTip 空字符串来取消关联特定Windows 窗体控件与工具提示的关联。 为 ToolTip 标题传递空字符串时, SetToolTip 方法从 的内部 HashTable 中删除对 Windows 窗体 控件的 ToolTip 引用。

还可以调用 ToolTip.RemoveAll 以删除所有文本并取消与所有 ToolTip Windows 窗体控件的关联。

如果应用程序未将多个Windows 窗体控件与单个工具提示相关联,则可以调用 Dispose 方法 ToolTip

此行为是设计使然。

请考虑Windows 窗体应用程序中的以下示例代码。 方法中的 CreateControls() 代码创建多个 TextBox 控件,调用 ToolTip.SetToolTip 以为每个 Control 分配 ToolTip 标题,并将控件添加到内部 ObservableCollection Controls 集合。 方法中的 RemoveControls() 代码遍历 ObservableCollection , 获取对每个控件的引用,然后将其从 ObservableCollection 和 窗体的 Controls 集合中删除,然后调用其 Dispose 方法。 这会导致每个 TextBox 控件从窗体中删除并释放,但每个 TextBox 和关联的 ToolTipInfo 实例仍扎根于托管堆中。 取消注释 方法中的 RemoveControls() 指定行会取消将 TextBox 与 ToolTip 关联,并允许对其进行垃圾回收。

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