如何在不同的应用程序状态下管理计时器,我使用的是 MVVM 方法?



我有一个工作正常的计时器,我遇到的问题是当应用程序处于睡眠模式或最小化时,或者当我按下后退按钮时,计时器应该只在我按下停止按钮时停止。

/// <summary>
/// Starts the timer
/// </summary>
private void StartCommandAction()
{
CancellationTokenSource cts = _cancellationTokenSource; // safe copy
Device.StartTimer(TimeSpan.FromSeconds(1),() =>
{
if (cts.IsCancellationRequested)
{
return false;
}
else
{
Device.BeginInvokeOnMainThread(() =>
{
var totalTimeInt = string.IsNullOrEmpty(TxtTotalTime.Value) ? 0  : int.Parse(TxtTotalTime.Value);
var totalSec = (int)TotalSeconds.TotalSeconds;
TimeSpan _TimeSpan = new TimeSpan(totalTimeInt, 0, totalSec); //TimeSpan.FromSeconds(TotalSeconds.TotalSeconds);
LblTime = string.Format("{0:00}:{1:00}:{2:00}", _TimeSpan.Hours, _TimeSpan.Minutes, _TimeSpan.Seconds);
IsVisibleTimerLabel = true;
Count();
});
return true;
}
});
IsVisibleButtonStart = false;
IsVisibleButton = true;
}

在不了解源代码的其余部分的情况下,我突然想到:您期望计时器事件每秒恰好引发一次,并使用文本表示来计算总时间。这可能适用于当前的定时器实现,但不能保证。更糟糕的是,您的实现对于不同的定时器实现并不健壮。

当你在每次迭代中总结你的时间时,总时间的误差会越来越大。根据您的用例,这可能无关紧要,但幸运的是,解决这个问题的方法也是解决您试图解决的问题的方法。

我的建议是:不要总结时代,而是引入一个固定的参考。按照第一个顺序,这可能是DateTime(如果精度对你来说很重要,你的解决方案看起来会有所不同,因此DateTime.Now的精度就可以了(,但Stopwatch也可以。

首次启动计时器时,将当前DateTime.Now值存储在成员变量中,并使用该值计算经过时间

CancellationTokenSource cts = _cancellationTokenSource; // safe copy
this._startedAt = DateTime.Now;
Device.StartTimer(TimeSpan.FromSeconds(1),() =>
{
if (cts.IsCancellationRequested)
{
return false;
}
else
{
Device.BeginInvokeOnMainThread(() =>
{
TimeSpan _TimeSpan = DateTime.Now - _startedAt;
LblTime = _TimeSpan.ToString("hh:mm:ss);
IsVisibleTimerLabel = true;
Count();
});
return true;
}
});

(请注意:要格式化TimeSpan,您可以使用带有格式字符串的ToString方法。请参阅TimeSpan.ToString的文档,了解如何根据您的需要格式化TimeSpan值(

这样,当返回到页面时,您只需重新启动计时器(不过不需要设置_startedAt(。因为您已经设置了_startedAt,所以计时器将继续运行并显示正确的时间。

相关内容

最新更新