gpt4 book ai didi

c# - 为什么从 System.ComponentModel.Component 继承会阻止对象被垃圾收集(完全)

转载 作者:行者123 更新时间:2023-11-30 19:41:51 26 4
gpt4 key购买 nike

我最初的问题是在继承自的类中注销自引用事件处理程序是否重要。成分。他们提供了一个 Disposed 事件,一次可以取消初始化。

但我在玩弄它并意识到了一些奇怪的事情:派生自 System.ComponentModel.Component 确实阻止了析构函数被调用(即使在应用程序结束时也是如此。

这是一个明确使用 GC.Collect 强制收集的示例(仅测试,从不在产品代码中使用它)

using System;
using System.ComponentModel;

namespace CSharpEventHandlerLifetime
{
public class LongLiving : Component
{

public LongLiving()
{
Console.WriteLine("Creating object");
// Disposed += (sender, args) => Console.WriteLine("Disposed");
}

~LongLiving()
{
Console.WriteLine("Destructor called");
}

}

class Program
{
public static void _create()
{
using (var l = new LongLiving())
{
Console.WriteLine("Generation is {0}", GC.GetGeneration(l));
}
}

static void Main(string[] args)
{
_create();

GC.Collect(); // this should call dtor of LongLiving


Console.ReadKey(); // wait before end
}
}
}

当我完全删除继承的 Component 类(将 using 更改为普通 new)或用 IDisposable 替换它(并实现一些空的 Dispose 方法)时,我清楚地看到调用 GC.Collect 调用 LongLiving 的 dtor。

我不理解这种行为,因为我至少希望在应用程序退出时进入 ~dtor,但从组件派生时它永远不会发生。

最佳答案

Component已经实现了 Disposable 模式,其中包括对 GC.SuppressFinalize 的调用完成时。 Disposeusing block 退出时被调用。

所以这个对象被垃圾收集了,它只是从来没有调用过它的终结器。

如果你有任何清理工作要做,你应该覆盖 Dispose(bool) .

例如这是 ComponentDispose 方法:

public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

关于c# - 为什么从 System.ComponentModel.Component 继承会阻止对象被垃圾收集(完全),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18586453/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com