1

我试图深入了解 Timer 将如何使用线程池。我写了以下简单的片段。

class Program
    {
        static private readonly Action Action = () => {
                                                     Thread.SpinWait(100 * 10000);
                                                     Interlocked.Increment(ref _data);
        };

        private static volatile int _data;

        static private Timer _threadCountChecker = new Timer(
            (obj) =>
                {
                    var t = Process.GetCurrentProcess().Threads;
                    Console.WriteLine("Using {0} threads.", t.Count);
                    Console.WriteLine(Program._data);
                }, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));

        static void Main(string[] args)
        {
            var l = new List<Timer>();

            for (int i = 0; i < 10; i++)
            {
                l.Add(new Timer((obj) => Action(), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)));
            }

            var exitEvent = new ManualResetEvent(false);
            exitEvent.WaitOne();
        }
    }

令人惊讶的是,这是我得到的输出:

使用 14 个线程。10 使用 14 个线程。18 使用 14 个线程。28 使用 14 个线程。39 使用 14 个线程。48 使用 15 个线程。58 使用 15 个线程。69 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80 使用 15 个线程。80

无论我继续运行该过程多长时间,数据变量都保持在 80。

有谁知道为什么变量在前 8 次迭代中更新并​​且停止递增?

4

1 回答 1

5

计时器收集了垃圾。在 eventWait.WaitOne() 调用之后添加此语句以解决该问题:

  GC.KeepAlive(l);

GC 处理 Release 构建中的局部变量的方式在此答案中有详细说明。

于 2013-10-01T17:38:44.237 回答