3

我最初的问题是,在继承自 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 派生时它永远不会发生。

4

1 回答 1

8

Component已经实现了 Disposable 模式,其中包括完成时的调用GC.SuppressFinalize。并且在块退出Dispose时被调用。using

所以对象是垃圾收集的,它只是永远不会调用它的终结器。

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

例如,这是ComponentsDispose方法:

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}
于 2013-09-03T07:35:51.920 回答