WinForms和事件处理程序

时间:2012-01-04 21:06:24

标签: c# winforms memory-management memory-leaks

默认情况下,当您创建一个Win-Form应用程序时,这是由Visual Studio生成的用于处理该表单的代码。

protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

这还够吗?或者我应该取消注册所有事件,以便垃圾收集器准备好收集控件?

        if (disposing && (components != null))
        {
            myButton.OnClick-= MyFunction; //may be here!!
            // ... all events used
            components.Dispose();

        }

3 个答案:

答案 0 :(得分:3)

表单必须取消注册将超过表单的实体的所有事件。如果表单取消注册来自与表单具有相同生命周期的实体的事件,则无关紧要。无论出于何种原因,正常的学说似乎是“不要担心取消注册事件,除非重要”。我认为订阅事件的所有对象在Dispose上取消订阅会更加清晰,但不幸的是vb.net和C#都没有提供任何甚至是远程干净的方法来实现这一点。使用实现IDisposable的依赖项,可以将构造包装在例程中,该例程将新创建的项添加到稍后要清理的事物列表中。然后,只需在列表中的所有内容上调用Dispose即可执行所有必要的清理。不幸的是,从.net的角度来看,没有很好的方法来编写一个通用例程,它将同时订阅一个事件并返回一个Action<>IDisposable或其他可以使用的对象。取消订阅。

答案 1 :(得分:0)

如果这是经常进行close and open操作的表单,并且在其中使用了大量事件,则重要取消注册所有事件 。 Cuase事件绝对消耗资源。

如果这是一段时间出现的形式,或者甚至可能无法出现,或者就是说,是的,应用程序的MainForm不重要来取消订阅活动

place如何做到这一点,我个人会在内部取消订阅,让我们在Closing覆盖内部,不在<{1}}

答案 2 :(得分:0)

不,垃圾收集器会处理它。事件永远不会再被引发,因为表单实例被处理,而该表单实例又处理了按钮。由于事件处理程序,表单和按钮之间存在循环引用,但垃圾收集器没有问题。