不删除事件处理程序会导致 .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 个控件,向其添加事件。

所以问题是:

  1. 当控件被清除()时,事件处理程序是否被删除?

如果不是,我将如何以编程方式清除事件处理程序,而无需单独遍历每个控件并删除其处理程序?

你正在做的事情是安全的,因为你扔掉的东西是保存引用的东西。 也就是说,每个Control都保存对委托的引用,该委托保存对具有事件处理程序的对象(通常是 Form 或其他一些长期对象)的引用,但具有事件处理程序的对象在从 UI 中删除控件后不保留对控件的引用。 Control变得完全无法访问(假设您没有出于其他目的持有对它的引用),因此它仍然"知道"长寿命对象是无关紧要的。 当垃圾回收器运行时,Control将消失,委托将随之消失。

另一方面,您不想做的是将短期对象注册为长期对象的事件处理程序(而不记得取消注册)。 当你这样做时,即使你认为你已经"删除"了短生存期的对象,长生存期对象仍然知道这个短生存期的对象,这使得它永远不会被垃圾回收,并且你拥有本质上是内存泄漏的托管内存版本(更不用说现在应该断开连接的对象仍将响应事件)。

如果控件不可见,则无法从 GUI 触发事件。无需分离事件。它们不会造成任何"伤害"。

最新更新