[英]How can I manage my timer on different application states, I'm using MVVM approach?
I have a timer that works fine, the problem I'm having is to keep the timer running when the app is on sleep mode or minimized or when I hit the back button, the timer should only stop when I hit the stop button of which I have done.我有一个工作正常的计时器,我遇到的问题是当应用程序处于睡眠模式或最小化或按下后退按钮时保持计时器运行,计时器应该只在我按下停止按钮时停止我已经做好了。
/// <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;
}
Without knowing the rest of your source code, the following struck me: You are expecting the timer event to be raised exactly once each second and taking the textual representation to calculate a total time.在不知道您的源代码的 rest 的情况下,以下内容让我印象深刻:您期望计时器事件每秒准确触发一次,并采用文本表示来计算总时间。 This may work for the current timer implementation, but this is not guaranteed.
这可能适用于当前的计时器实现,但不能保证。 Even worse, your implementation is not robust against different timer implementations.
更糟糕的是,您的实现对于不同的定时器实现并不健壮。
When you sum up your times each iteration, the error of the total time will grow and grow.当你总结你每次迭代的时间时,总时间的误差会越来越大。 Depending on your use-case this may be irrelevant, but luckily, the remedy to this issue is the remedy to the issue you're trying to solve, too.
根据您的用例,这可能无关紧要,但幸运的是,对这个问题的补救措施也是对您要解决的问题的补救措施。
My suggestion is: Refrain from summing up the times, but introduce a fixed reference.我的建议是:不要总结时代,而要引入固定的参考。 In the first order this might be a
DateTime
(if precision was a matter to you, your solution would look different, hence the precision of DateTime.Now
will do), but a Stopwatch
would do the trick either.在第一个顺序中,这可能是
DateTime
(如果对您来说精度很重要,那么您的解决方案看起来会有所不同,因此DateTime.Now
的精度会起作用),但Stopwatch
也可以解决问题。
When starting the timer the first time, store the current DateTime.Now
value in a member variable and use this to calculate the elapsed time第一次启动计时器时,将当前的
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;
}
});
( Please note: To format a TimeSpan
you can use the ToString
method with a format string. Please see the documentation of TimeSpan.ToString
on how to format TimeSpan
values according to your needs) (请注意:要格式化
TimeSpan
,您可以使用带有格式字符串的ToString
方法。有关如何根据需要格式化TimeSpan
值,请参阅TimeSpan.ToString
的文档)
This way, when returning to the page, you can just restart the timer ( without setting _startedAt
, though).这样,当返回页面时,您只需重新启动计时器(但无需设置
_startedAt
)。 Because you've already set _startedAt
, the timer will continue to run and show the correct time.因为您已经设置
_startedAt
,所以计时器将继续运行并显示正确的时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.