我的原始问题是,在继承自例如Component的类中,注销自引用事件处理程序是否重要。它们提供了一个Disposed事件,可以取消初始化内容。
但我进行测试时发现了一些奇怪的事情:从System.ComponentModel.Component派生会完全阻止析构函数被调用(即使在应用程序结束时也是如此)。
以下是一个样例,明确使用GC.Collect来强制收集(仅用于测试,永远不要在生产代码中使用)。
但我进行测试时发现了一些奇怪的事情:从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派生时,它永远不会发生。
WaitForPendingFinalizers
的调用,而不仅仅是立即运行第二个收集器,这是你第一条评论所暗示的解决方法。 - Damien_The_Unbeliever