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

Xamarin Forms中如何计算计时器从启动到当前的已流逝时长

计时器流逝时长最优实现方案

原有代码的问题

你当前采用定时器每秒累加1秒的实现方式会存在累计误差:设备定时器的触发间隔并非100%精准,遇到App退入后台、主线程阻塞的场景时,定时器触发会出现延迟,长期运行后计时偏差会越来越明显。

优化实现逻辑

通过「记录启动基准时间戳」的方式计算流逝时长,从根源避免累计误差:

  1. 启动计时器时同时记录两个值:历史累计时长、本次启动时刻的本地时间
  2. 每次定时器触发时,直接用当前时间减去启动时刻得到本次启动后的流逝时长,再叠加历史累计时长就是总计时长
  3. 该方案就算出现定时器丢触发、延迟触发的情况,下次更新时也会自动校准到正确的时间值

优化后代码

CancellationTokenSource cts = _cancellationTokenSource; // safe copy

// 计时器启动逻辑
TimeSpan initialTotalTime = TimeSpan.FromMinutes(TimeSheet.TotalTime);
DateTime timerStartAt = DateTime.Now; // 记录本次计时器启动的基准时间

// 1秒间隔定时器
Device.StartTimer(TimeSpan.FromSeconds(1), () => {
    if (cts.IsCancellationRequested)
    {
        return false;
    }
    Device.BeginInvokeOnMainThread(() => {
        // 直接用当前时间减启动时间计算流逝时长,无累计误差
        TimeSpan elapsedSinceStart = DateTime.Now - timerStartAt;
        TimeSpan totalTime = initialTotalTime + elapsedSinceStart;
        
        string displaytime = totalTime.ToString(@"h\:m\:s");
        TimeSheet.TotalTimeForDisplay = displaytime;

        Console.WriteLine("Timer");
        Console.WriteLine(displaytime);
    });
    return true;
});

额外适配说明

  • 支持后台运行场景,下次回到前台定时器触发时会自动计算正确的总时长,不会丢失后台的计时数据
  • 如果需要实现暂停后继续计时的功能,只需要在暂停时把当前的totalTime存为新的历史累计时长,下次启动时重新记录timerStartAt即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:39:02