终结者如何运作?

时间:2013-04-08 12:42:49

标签: c# .net

我试图弄清楚c#中的GC /终结器是如何工作的,所以我编写了以下程序。但是在ReadKey之后,终结器被称为36193次。我认为应该在程序完成并且AppDomain卸载时调用一次。我在这里缺少什么,这是如何工作的?

    private class GCAnalyzer
    {
        private static int count = 0;
        ~GCAnalyzer()
        {
            if (!AppDomain.CurrentDomain.IsFinalizingForUnload())
            {
                count++;
                GC.ReRegisterForFinalize(this);
                Console.WriteLine("GC " + count);
            }
        }
    }

    static void Main(string[] a)
    {
        new GCAnalyzer();

        Console.ReadKey();
    }

2 个答案:

答案 0 :(得分:2)

如果我读了这个,那么当对象被“取消链接”时你正在调用~GCAnalyzer(),并且在那段代码中,你说它还没有准备好通过GC.ReRegisterForFinalize(this)“取消链接”,意思是接下来检查它仍然没有使用,它的结束代码运行...重新注册自己......等等。

答案 1 :(得分:0)

关键是添加!Environment.HasShutdownStarted检查。然后在每个集合上调用终结器并将其放回到最终化列表中。所以在这个程序中,终结器被调用3次。每个GC.Collect两次,然后在完成列表中注册,第三次应用程序关闭然后不重新注册,以便它可以正常关闭dow。

    private class GCAnalyzer
    {
        private static int count = 0;
        ~GCAnalyzer()
        {
            Console.WriteLine("GC " + count);
            if (!AppDomain.CurrentDomain.IsFinalizingForUnload() &&!Environment.HasShutdownStarted)
            {
                count++;
                GC.ReRegisterForFinalize(this);                    
            }
        }
    }

    static void Main(string[] a)
    {
        new GCAnalyzer();

        Console.ReadKey();

        GC.Collect();

        Console.ReadKey();

        GC.Collect();
    }