不删除事件处理程序会导致 .Net 出现问题吗?
Does not removing event Handlers cause problems in .Net?
我有以下代码:
public void LoadPage()
{
LayoutPanel.Controls.Clear();
ContentObjects = LoadContentObjects();
foreach (string img in ContentObjects)
{
thumbnail = new ctrlThumbnailControl(img);
LayoutPanel.Controls.Add(thumbnail);
thumbnail.ThumbnailSelected += Thumbnail_ThumbnailSelected;
}
}
private void Thumbnail_ThumbnailSelected(string PathToMedia)
{
lblFileName.Text = PathToMedia;
}
我为每个加载的图像创建一个缩略图控件(每页限制为 150 个)。缩略图控制器有一个事件,该事件在悬停在控件上时引发。
所以这个页面有 150 个带有事件的控件。当我加载下一页时,我不会删除事件。我确实删除了控件。并创建另外 150 个控件,向它们添加事件。
所以问题是:
- 当控件被 Clear()ed 时,事件处理程序是否被删除?
如果不是,我将如何以编程方式清除事件处理程序而不单独检查每个控件并删除它的处理程序?
如果控件不可见,则无法从 GUI 触发事件。无需分离事件。他们不做任何 "harm".
你正在做的事情是安全的,因为你扔掉的东西是持有参考的东西。也就是说,每个 Control
都持有对委托的引用,该委托持有对具有事件处理程序的对象的引用,通常是 Form
或其他一些长期存在的对象,但具有从 UI 中删除后,事件处理程序不保留对控件的引用。 Control
变得完全无法访问(假设您没有出于其他目的持有对它的引用),因此它仍然 "knows" 关于长期存在的对象是无关紧要的。当垃圾收集器运行时,Control
将消失,委托也会随之消失。
另一方面,您不想做的是将一个短期对象注册为一个长期对象的事件处理程序(不记得注销).当你这样做时,即使你认为你已经 "removed" 短命对象,长命对象仍然知道短命对象,这使它保持活着,这样它就永远不会被垃圾收集,你本质上是内存泄漏的托管内存版本(更不用说现在应该断开连接的对象仍将响应事件)。
我有以下代码:
public void LoadPage()
{
LayoutPanel.Controls.Clear();
ContentObjects = LoadContentObjects();
foreach (string img in ContentObjects)
{
thumbnail = new ctrlThumbnailControl(img);
LayoutPanel.Controls.Add(thumbnail);
thumbnail.ThumbnailSelected += Thumbnail_ThumbnailSelected;
}
}
private void Thumbnail_ThumbnailSelected(string PathToMedia)
{
lblFileName.Text = PathToMedia;
}
我为每个加载的图像创建一个缩略图控件(每页限制为 150 个)。缩略图控制器有一个事件,该事件在悬停在控件上时引发。
所以这个页面有 150 个带有事件的控件。当我加载下一页时,我不会删除事件。我确实删除了控件。并创建另外 150 个控件,向它们添加事件。
所以问题是:
- 当控件被 Clear()ed 时,事件处理程序是否被删除?
如果不是,我将如何以编程方式清除事件处理程序而不单独检查每个控件并删除它的处理程序?
如果控件不可见,则无法从 GUI 触发事件。无需分离事件。他们不做任何 "harm".
你正在做的事情是安全的,因为你扔掉的东西是持有参考的东西。也就是说,每个 Control
都持有对委托的引用,该委托持有对具有事件处理程序的对象的引用,通常是 Form
或其他一些长期存在的对象,但具有从 UI 中删除后,事件处理程序不保留对控件的引用。 Control
变得完全无法访问(假设您没有出于其他目的持有对它的引用),因此它仍然 "knows" 关于长期存在的对象是无关紧要的。当垃圾收集器运行时,Control
将消失,委托也会随之消失。
另一方面,您不想做的是将一个短期对象注册为一个长期对象的事件处理程序(不记得注销).当你这样做时,即使你认为你已经 "removed" 短命对象,长命对象仍然知道短命对象,这使它保持活着,这样它就永远不会被垃圾收集,你本质上是内存泄漏的托管内存版本(更不用说现在应该断开连接的对象仍将响应事件)。