【问题标题】:Strange behaviour of a System.Threading.TimerSystem.Threading.Timer 的奇怪行为
【发布时间】:2013-10-07 23:26:48
【问题描述】:

我正在尝试深入了解 Timer 将如何使用线程池。我写了以下简单的sn-p。

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 次迭代中更新并​​且停止递增?

【问题讨论】:

    标签: c# multithreading timer interlocked interlocked-increment


    【解决方案1】:

    计时器被垃圾收集。在 eventWait.WaitOne() 调用之后添加这个语句来解决这个问题:

      GC.KeepAlive(l);
    

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

    【讨论】:

      猜你喜欢
      • 2018-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 2015-07-20
      • 2010-10-03
      • 2021-07-12
      • 2013-10-04
      相关资源
      最近更新 更多