简体   繁体   English

C#计时器与Datetime.Now同步

[英]C# timer synchronized with Datetime.Now

In C# how to create a timer that synchronize with tick of system DateTime. 在C#中,如何创建与系统DateTime的滴答同步的计时器。 custom timer should tick whenever the seconds change for DateTime.Now 自定义计时器应该在DateTime.Now的秒数更改时打勾

You will find if you check some of the previous questions on SO, you are going to have a very hard time getting accuracy with your timer. 您会发现,如果您检查了SO上的一些先前问题,您将很难获得准确的计时器。 Here is a small sample of previous questions: 以下是先前问题的一小部分:

Here is another previous question which may provide you some help. 这是另一个先前的问题 ,可能会为您提供帮助。

What would be your desired precision ? 您想要的精度是多少?

If you say that 1ms is precise enough (or 10, or 100), you could always do a loop which compares the current time and one saved from the previous iteration, and start a thread when the seconds value of the current time value changes... 如果您说1ms足够精确(或10或100),则可以始终执行一个循环,将当前时间与上一次迭代保存的时间进行比较,并在当前时间值的秒值更改时启动线程。 ..

您可以使用一些时间表库,例如Quartz.net,它提供了示例并且易于使用: http : //quartznet.sourceforge.net/

This code uses a System.Threading.Timer. 此代码使用System.Threading.Timer。 It will look at the millisecond-offset the trigger is called. 它将查看调用触发器的毫秒偏移量。 If the error is outside the accepted range, it will re-adjust the timer and it will correct the interval by averaging the error per tick. 如果错误超出了可接受的范围,它将重新调整计时器,并通过平均每个刻度的错误来校正间隔。

class Program {
    const int MAX_ERROR_IN_MILLISECONDS = 20;
    const int ONE_SECOND = 1000;
    const int HALF_SECOND = ONE_SECOND / 2;

    private static System.Threading.Timer timer;

    static void Main(string[] args) {

        timer = new System.Threading.Timer(Tick);

        timer.Change(ONE_SECOND - DateTime.Now.Millisecond, ONE_SECOND);
        Console.ReadLine();
    }

    private static int ticksSynced = 0;
    private static int currInterval = ONE_SECOND;
    private static void Tick(object s) {
        var ms = DateTime.UtcNow.Millisecond;
        var diff = ms > HALF_SECOND ? ms - ONE_SECOND : ms;
        if (Math.Abs(diff) < MAX_ERROR_IN_MILLISECONDS) {
            // still synced
            ticksSynced++;
        } else {
            // Calculate new interval
            currInterval -= diff / ticksSynced;
            timer.Change(ONE_SECOND - ms, currInterval);
            Console.WriteLine("New interval: {0}; diff: {1}; ticks: {2}", currInterval, diff, ticksSynced);
            ticksSynced = 0;
        }
        Console.WriteLine(ms);
    }
}

As you can see, you cannot trigger exactly on the second change in Windows. 如您所见,您不能完全在Windows中的第二次更改上触发。 You can try to get close. 您可以尝试靠近。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM