我最初的问题是,在继承自 Component 的类中取消注册自引用事件处理程序是否重要。他们提供了一个 Disposed 事件,在该事件中可以取消初始化东西。
但我在玩它并意识到一些奇怪的事情:派生System.ComponentModel.Component
确实阻止了析构函数被调用(即使在 application.
这是一个显式使用 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
为 plain new
)或将其替换为 IDisposable (并实现一些空的 Dispose 方法)时,我清楚地看到调用 GC.Collect 调用了 LongLiving 的 dtor。
我不理解这种行为,因为我至少希望在应用程序退出时会闯入 ~dtor,但从 Component 派生时它永远不会发生。