扑面秒表的运行速度比预期的要慢
我的秒表比实际时间慢0.5倍 (例如,实时时间为1分钟,秒表显示〜34秒)。
这是提供商代码:
class TimerState extends ChangeNotifier {
late String _stringTimer;
late Duration _duration;
Timer? _timer;
TimerState() {
_stringTimer = '00:00.00';
_duration = const Duration();
}
String get get => _stringTimer;
void start() {
_timer = Timer.periodic(const Duration(milliseconds: 1), (_) => _addTime());
}
void _addTime() {
_duration = Duration(milliseconds: _duration.inMilliseconds + 1);
_formattedTimer();
}
void _formattedTimer() {
String twoDigits(int n) => n.toString().padLeft(2, '0');
final milliseconds = twoDigits((_duration.inMilliseconds.remainder(1000) / 10).floor());
final seconds = twoDigits(_duration.inSeconds.remainder(60));
final minutes = twoDigits(_duration.inMinutes.remainder(60));
_stringTimer = '$minutes:$seconds.$milliseconds';
notifyListeners();
}
}
My stopwatch is running 0.5x slower than actual time
(e.g. while the real time is 1 minute, the stopwatch shows ~34 seconds).
Here is the Provider code:
class TimerState extends ChangeNotifier {
late String _stringTimer;
late Duration _duration;
Timer? _timer;
TimerState() {
_stringTimer = '00:00.00';
_duration = const Duration();
}
String get get => _stringTimer;
void start() {
_timer = Timer.periodic(const Duration(milliseconds: 1), (_) => _addTime());
}
void _addTime() {
_duration = Duration(milliseconds: _duration.inMilliseconds + 1);
_formattedTimer();
}
void _formattedTimer() {
String twoDigits(int n) => n.toString().padLeft(2, '0');
final milliseconds = twoDigits((_duration.inMilliseconds.remainder(1000) / 10).floor());
final seconds = twoDigits(_duration.inSeconds.remainder(60));
final minutes = twoDigits(_duration.inMinutes.remainder(60));
_stringTimer = '$minutes:$seconds.$milliseconds';
notifyListeners();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的方法在每个计时器事件上添加了计时器间隔(1MS)。这是一种不好的方法,因为它假设您的计时器完全在每毫秒内射击而没有错误的空间。如果错过任何计时器事件,您还将浪费时间(如果您的工作时间超过1ms,可能会发生)。错误将累积。
另请注意,1MS非常短。每毫秒每毫秒重新绘制小部件将以每秒1000帧的速度更新它。
一种更好的方法是记录开始时间,在每个计时器事件上,将
datetime.now()
的差异计算为开始时间(例如).Difference(start Time); )。这将防止错误积累。更好的是,请使用astopwatch
为您做到这一点的对象。您还应该选择一个更合理的计时器间隔;选择比屏幕更快的刷新率的速度浪费的速度是浪费的。
Your approach adds the timer interval (1ms) on each timer event. That is a bad approach because it assumes that your timer fires exactly on every millisecond with no room for error. You also will lose time if any timer events are missed (which might happen if you ever do work that takes longer than 1ms). Error will accumulate.
Also note that 1ms is very short. Redrawing your widget every millisecond would be updating it at a rate of 1000 frames per second.
A much better approach would be to record the start time and, on each timer event, compute the difference from
DateTime.now()
to the start time (e.g.var elapsed = DateTime.now().difference(startTime);
). That will prevent error from accumulating. Better yet, use aStopwatch
object which does that for you.You also should pick a more reasonable timer interval; picking a rate faster than your screen's refresh rate is wasteful.