c# - System.Threading.Timer 的奇怪行为

标签 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();
        }
    }

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

Using 14 threads. 10 Using 14 threads. 18 Using 14 threads. 28 Using 14 threads. 39 Using 14 threads. 48 Using 15 threads. 58 Using 15 threads. 69 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80 Using 15 threads. 80

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

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

最佳答案

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

  GC.KeepAlive(l);

GC 在发布版本中处理局部变量的方式在 this answer 中有详细解释。 .

关于c# - System.Threading.Timer 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19122353/

相关文章:

android - 我在这个简单的 android 代码中缺少什么?

java - java线程等待获取不到锁的状态是什么

c# - 在本地运行一次计时器触发的 Azure 函数的最简单方法是什么?

c# - 如何轮询目录中的文件

c# - 替换 "\"的奇怪行为

c# - Web 应用程序错误 : Sequence contains more than one element

silverlight - Silverlight 中的异步 Web 服务器调用和最大 HTTP 连接数

java - 等待计时器/进程完成后再继续

c# - 如何区分模型和实体?

c# - 动态加载类型的 SerializationException