Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 每分钟计时一次_C#_Multithreading_Timer - Fatal编程技术网

C# 每分钟计时一次

C# 每分钟计时一次,c#,multithreading,timer,C#,Multithreading,Timer,我不能让计时器在每分钟1:00、1:01、1:02等时触发一次。相反,当计时器每次迭代执行漂移几秒时 internal void StartTimer() { DateTime nowEastern = CalendarEntity.Calendar.GetEasternTime(); int secondsInterval = 5; double additionalSeconds = secondsInterval - now

我不能让计时器在每分钟1:00、1:01、1:02等时触发一次。相反,当计时器每次迭代执行漂移几秒时

   internal void StartTimer()
    {
        DateTime nowEastern = CalendarEntity.Calendar.GetEasternTime();

        int secondsInterval = 5;

        double additionalSeconds = secondsInterval - nowEastern.TimeOfDay.TotalSeconds % secondsInterval;
        if (additionalSeconds == 0)
        {
            additionalSeconds = 1;
        }
        var nearestOnOneMinutes = new DateTime(
            nowEastern.Year,
            nowEastern.Month,
            nowEastern.Day,
            nowEastern.Hour,
            nowEastern.Minute,
            nowEastern.Second
        ).AddSeconds(additionalSeconds);

        TimeSpan timeToStart = nearestOnOneMinutes.Subtract(nowEastern);
        TimeSpan tolerance = TimeSpan.FromSeconds(1);
        if (timeToStart < tolerance)
        {
            timeToStart = TimeSpan.Zero;
        }

        timer_onem = new System.Threading.Timer(OnTimedEvent, null,
                                    (int)timeToStart.TotalMilliseconds, Timeout.Infinite);
    }

    private static void OnTimedEvent(object o)
    {
        var minute = DateTime.Now.Minute;
        var second = DateTime.Now.Second;
        if (minute != lastMinute && second % 60 < 2)
        {
            lastMinute = minute;
            CodeToExecute();
        }
    }

    static void CodeToExecute()
    {
        double tms = 60000;

        // code here
        int wait = 60 - System.DateTime.Now.Second;

        timer_onem.Change(Convert.ToInt64(tms) - wait, Timeout.Infinite);
    }

计时器
只能保证不快于
间隔

所以你需要打电话,每秒钟说一次,然后检查一分钟

为了获得更高的精度,您必须每1/2秒或更高的时间检查一次

信息论的一条基本规则是,要以给定的分辨率(在您的情况下为1秒)进行测量,您需要以比该分辨率高一倍的分辨率进行采样。因此,要测量20kHz,您需要一个比2x20kHz(例如44.1kHz)更好的smpling速率。(认得数字吗?)

如果你不想经常称之为“一个时间点”的话,您可以编写更复杂的代码,在每个
勾选
时将
计时器重置。间隔
在剩余时间的一半以下
,直到下一整分钟,直到小于500ms


但是,在设置预期时间时,代码中会发生相当复杂的事情;确保它们不是真正的问题。由于计时器的精度不高,不应出现不断增长的漂移,除非您“收集”错误。

请参见编辑1。这似乎无助于增加定时事件的频率。你是说为了让我在一个整数分钟的边界上以+/-1秒的漂移(或60000毫秒)执行某些操作,我必须每500毫秒触发一次计时器?这似乎很荒谬。所以1:01:01,1:02:02,1:03:02,1:04:01是可以的,但是我得到了1:01:02,1:02:04,1:03:06,等等,在秒上单调递增。这是信息论的一条基本规则,它说,要用给定的分辨率进行测量,你需要用两倍以上的分辨率进行采样。因此,要测量20kHz,您需要比2x20kHz更好,比如44kHz。(识别数字?)当然,如果只需要测量一个时间点,这是浪费;请参阅我的最后一段,了解一个优化但仍然简单的算法。-不确定,但如果不是,可能代码中的其他东西可能是罪魁祸首。事实上,漂移的增长肯定有不同的原因。我建议您注销预期时间,看看它们是否合理。您执行的代码是否会产生大量工作负载?如果是这样的话,你可能应该把它移到一个后台工作者那里..不,完全是被动代码。
    timer_onem = new System.Threading.Timer(OnTimedEvent, null,
                                    (int)timeToStart.TotalMilliseconds, 1000);

    private static void OnTimedEvent(object o)
    {
        var minute = DateTime.Now.Minute;

        if (minute != lastMinute)
        {
            lastMinute = minute;
            CodeToExecute();
        }
    }

    private static void CodeToExecute()
    {
        if (bGenerate)
        {
            double tms = 1000;
            // code
            timer_onem.Change(Convert.ToInt64(tms), 1000);
        }
    }