我是否需要取消订阅表格中的活动?

Dan*_*lba 2 c# events dispose winforms

我试图了解Control事件是如何取消订阅的.假设我有一个文本框,我已经TextChanged使用WinForms设计器订阅了该事件.

TextChanged事件是否会在析构函数中自动取消订阅Textbox,或者我是否必须明确取消订阅以避免内存泄漏?

public void InitializeComponents()
{
    ...
    this.emailTextBox.TextChanged += emailTextBox_TextChanged;
    ...
}

public override void Dispose()
{
    if( disposing )
    {
        // DO I REALLY NEED THIS LINE?
        this.emailTextBox.TextChanged -= emailTextBox_TextChanged;
        if(components != null)
        {
            components.Dispose();
        }
    }
    base.Dispose( disposing );
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*ick 6

在这种情况下,我相信可以不取消订阅,因为您订阅的TextBox完全包含在父控件中(或者这就是我所假设的.)

因此,当不存在对父控件的进一步引用时,将不会对TextBox进行任何外部引用,因此两个对象都将符合GC的条件.

在某些情况下,您取消订阅事件以防止内存泄漏,因为事件(在其订阅者列表中)所持有的引用与任何其他引用相同,并且会阻止订阅者进行GC.

当对象订阅外部对象上的事件(即不属于此对象)时,可能会发生这种情况.在这种情况下,订阅者只有在订阅对象符合GC条件后才有资格获得GC.


sup*_*cat 5

订阅来自较长寿命对象的事件的任何对象都应该实现,IDisposable并且应该在Disposed 时取消订阅这些事件.从概念上讲,没有理由为什么对象在处理时不应取消订阅所有事件,因为这样做可以避免在订阅事件的对象活得超过预期的情况下出现问题.遗憾的是,.NET中的事件体系结构没有提供任何机制来方便地确保在处理对象时清理事件,并且在处理对象时让代码取消订阅一堆事件可能会使确保少数事件真正变得更加困难需要清理的是那些.