System.Threading.Timer的奇怪行为

Kla*_*ark 1 c# multithreading timer interlocked interlocked-increment

我试图了解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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

使用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次迭代中得到更新并且只是停止递增?

Han*_*ant 5

计时器收集了垃圾.在eventWait.WaitOne()调用之后添加此语句来修复:

  GC.KeepAlive(l);
Run Code Online (Sandbox Code Playgroud)

本回答详细介绍了GC处理Release版本中局部变量的方式.