You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让方法在每个循环周期结束前10秒精准触发?

问题根源

你现在的触发时间越来越早,核心原因是120秒周期结束后没有重置Stopwatch。举个例子:

  • 第一次触发在累计110秒(1:50),没问题;到120秒时你停了timer和stopwatch,但没把stopwatch归零
  • 第二次启动后,累计时间从120秒开始算,这时候220秒(3:40)的时候220%110=0,就触发了——但你要的是第二个120秒周期的第110秒,也就是120+110=230秒(3:50),自然就提前了10秒
  • 后面每次都会差10秒,触发时间越来越早
修正代码

给你两种靠谱的实现方式,选哪种都行:

方式1:周期结束重置计时器(推荐)

每次120秒到点后,把Stopwatch归零,这样每个周期的计时都是从零开始,判断110秒触发就准了:

private void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
    Application.Current.Dispatcher.BeginInvokeOnMainThread(() =>
    {
        MainTimer.Text = stopwatch.Elapsed.ToString(@"hh\:mm\:ss");
        double currentCycleSec = stopwatch.Elapsed.TotalSeconds;
        Tasklabel.Text = currentCycleSec.ToString();

        // 触发周期内第110秒的操作(用误差范围避免浮点精度坑)
        if (Math.Abs(currentCycleSec - 110) < 0.1)
        {
            // 这里写你要触发的方法
            // do sth
        }

        // 120秒周期结束,重置计时准备下一轮
        if (currentCycleSec >= 120)
        {
            Value = false;
            stopwatch.Stop();
            stopwatch.Reset(); // 关键:把计时器归零
            timer.Stop();

            // 如果需要自动开启下一个周期,解开下面的注释
            // stopwatch.Start();
            // timer.Start();

            // 这里写周期结束要执行的操作
            // do sth
        }
    });
}

方式2:不重置计时器,计算当前周期内的时间

要是不想重置Stopwatch,就用总时间对120取余,算出当前正处在这个120秒周期的第几秒,再判断是不是到110秒:

private void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
    Application.Current.Dispatcher.BeginInvokeOnMainThread(() =>
    {
        MainTimer.Text = stopwatch.Elapsed.ToString(@"hh\:mm\:ss");
        double totalSec = stopwatch.Elapsed.TotalSeconds;
        Tasklabel.Text = totalSec.ToString();

        // 算出当前在这个120秒周期里的时间
        double currentCycleSec = totalSec % 120;

        // 判断是否到周期内的110秒
        if (Math.Abs(currentCycleSec - 110) < 0.1)
        {
            // 执行你的目标操作
            // do sth
        }

        // 120秒周期结束的逻辑(取余后接近0就说明到点了)
        if (Math.Abs(currentCycleSec) < 0.1 && totalSec > 0)
        {
            Value = false;
            timer.Stop();

            // 周期结束的操作
            // do sth
        }
    });
}
重要提醒
  • 别直接用==判断浮点数相等!比如currentCycleSec == 110很可能因为计时精度问题判断失败,用Math.Abs(差值) < 0.1这种误差范围的方式更稳妥
  • 确保你的Timer间隔设置合理,比如设成1000毫秒(每秒触发一次),这样判断的精度足够
  • 如果需要循环执行120秒周期,记得在周期结束后重新启动Stopwatch和Timer

内容的提问来源于stack exchange,提问作者Marsjanin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:15:16