System.Timers.Timer 奇怪的行为

System.Timers.Timer strange behaviour

这是一个代码。 运行 并立即按住 P。您应该两次看到第一次约会。我懂了。我真的不知道为什么会这样。我想了解一下。有人可以清楚地向我解释吗?

using System;
using System.Timers;
using System.Diagnostics;

namespace Timer1
{
    class Program
    {
        static Stopwatch stopwatch = new Stopwatch();

        static Timer timer;

        static int interval = 1000;

        static void Main(string[] args)
        {
            Console.SetBufferSize(1000, 1000);

            timer = new Timer(interval);
            timer.Elapsed += Function;
            timer.Interval = interval;
            timer.Enabled = true;

            stopwatch.Start();

            while (true)
            {
                ConsoleKey key = Console.ReadKey(true).Key;

                if (key == ConsoleKey.P)
                {
                    int temp = interval - (int)stopwatch.ElapsedMilliseconds;

                    if (temp > 0)
                        timer.Interval = temp;

                    else
                        Function(null, null);
                }

                else
                {
                    timer.Dispose();
                    break;
                }

                Console.ReadKey(true);
            }
        }

        static public void Function(object sender, EventArgs e)
        {
            timer.Interval = interval;
            Console.WriteLine(DateTime.Now);
            stopwatch.Reset();
            stopwatch.Start();
        }
    }
}

根据您编写代码的方式,您有两条通往 Function() 的路径。一种方法是当计时器实际耗尽并且 Function() 结果为 "handled" 时。另一条路是when

interval - stopwatch.ElapsedMilliseconds

不大于0,此时直接调用Function()。

您似乎在使用 System.Timers.Timer。这是线程池线程上的 运行。由于您有多个线程 运行ning,因此两者都可以调用 Function()。您可能认为您通过在 Function() 中重置内部和秒表来防止这种情况发生,但是 Console.WriteLine() 足以允许一个线程延迟并让另一个线程 运行(在多处理器计算机上,两个线程可以在不同的处理器上同时 运行)。

根据您的逻辑性质,可以保证计时器间隔将在您的间隔测试达到 0 的几乎同时触发(调用处理程序),因此您可以预期它 运行 通过两条路径。

这个例子看起来不是很有用。是单纯的理解定时器吗?如果愿意,您可以更改时间间隔,但是当您将其大致更改为原来(或应该的)时,为什么还要费心呢?