本文可帮助你解决以下问题:如果错误地使用
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();