日期:2014-05-18  浏览次数:20724 次

质疑CLR Via C#中的一段代码,求指教狠批,只要能求得答案!!
这个问题困扰了大半个月了,睡觉之前老在琢磨!憋不住了来CSDN求解释!大恩不言谢!

代码是该书第三版 泛型部分P244
C# code
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections;

namespace GenericsTest
{
    sealed class Program
    {
        static void Main(string[] args)
        {
            ValueTypePerfTest();
            ReferenceTypePerfTest();
            Console.ReadKey();
        }

        private static void ValueTypePerfTest()
        {
            const int count = 10000000;
            using (new OperationTimer("List<Int32>"))
            {
                List<Int32> l = new List<int>(count);
                for (Int32 n = 0; n < count; n++)
                {
                    l.Add(n);
                    Int32 x = l[n];
                }
                l = null;

            }

            using (new OperationTimer("ArrayList of Int32"))
            {
                ArrayList a = new ArrayList();
                for (Int32 n = 0; n < count; n++)
                {
                    a.Add(n);
                    Int32 x = (Int32)a[n];
                }
                a = null;
            }
        }

        private static void ReferenceTypePerfTest()
        {
            const int count = 10000000;
            using (new OperationTimer("List<String>"))
            {
                List<string> l = new List<string>();
                for (Int32 i = 0; i < count; i++)
                {
                    l.Add("X");
                    String x = (String)l[i];
                }
                l = null;
            }
            using (new OperationTimer("ArrayList Of  String"))
            {
                ArrayList a = new ArrayList();
                for (Int32 i = 0; i < count; i++)
                {
                    a.Add("X");
                    String x = (String)a[i];
                }
                a = null;
            }

        }
    }


    internal sealed class OperationTimer : IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("{0:###0.00000000} 秒, (GCS={1}) {2}", (Stopwatch.GetTimestamp() - m_startTime) / (double)Stopwatch.Frequency, GC.CollectionCount(0) - m_collectionCount, m_text);
        }

        private Int64 m_startTime;
        private String m_text;
        private Int32 m_collectionCount;
        public OperationTimer(String text)
        {
            PrepareForOperation();
            m_text = text;
            m_collectionCount = GC.CollectionCount(0);
            m_startTime = Stopwatch.GetTimestamp();

        }

        private static void PrepareForOperation()
        {
            GC.Collect();
           【 GC.WaitForPendingFinalizers();
            GC.Collect();】
        }
    }
}


我要质疑的部分是【】包围的代码(其他部分代码我很清楚其目的),我认为这部分代码从【理论上】可以删除,我的理由是:
C# code
GC.WaitForPendingFinalizers();

挂起当前线程,直到处理终结器队列的线程清空该队列为止。( MSDN的释义)

挂起当前线程是应用程序的线程,处理终结器队列(也即Freachable队列)的线程是CLR专配线程,具有高优先级和特殊待遇,当freachable队列被清空时,会完成对每个对象的Finalize调用,这样对象才成为真正的垃圾。

具备Finalize方法的对象至少需要两次GC(排除代的提升作用),所以后面又加了句GC.Collect(),手动回收那些已经终结的对象的内存。

WaitForPendingFinalizers调用时,会使得应用程序的所有线程挂起睡眠直到所有Finalize方法调用完毕。
那些具备Finalize方法的对象才真正成为垃圾,所以问题来了,这个方法明显是针对处理终结器队列操作的,也就是那些具备Finalize方法的对象,但在这段代码中所有对象都没有析构函数,为何需要调用该方法?!?


------解决方案--------------------
sample just sample...有时候例子就是给人看看怎么写而已,未必有意义...所以,莫钻牛角尖...

ps:我没看过这书,你摘得这段又缺少上下文,说实在的我也不知道它要干什么...你等大侠出现吧...
------解决方案--------------------
恩,值得深思