周期性计时器有时会延迟,并且不会故意颤动



颤振中的计时器的行为与预期不同
如果我以毫秒为单位为每个周期调用特定的函数,则
它可能会滞后于该周期
即使我只测试计时器而没有其他代码,它也确实测试了
当我使用其他代码进行测试时,延迟的程度变得很严重
如果延迟保持在~99毫秒也没关系,然而,如果我在应用程序中使用计时器,它会跳到100到1000毫秒。

我在Isolate中测试了Timer(dart:async(、Metronome(Quiver库(、Timer(dart:异步(
一个有趣的现象是,当我将这些计时器设置为相同的周期并启动时,
这些计时器在类似的时刻延迟了类似的持续时间。例如,当我在应用程序代码中测试这些计时器时,这三个计时器同时延迟1000毫秒。(大量使用内存?(

下面是测试代码。我正在测试Galaxy Tab S4。(真实设备(

如何使用以毫秒为单位的计时器?

//code for isolate
DateTime lastIsolate;
DateTime currentIsolate;
int isolateCounter = 0;
void timerTest(SendPort sendPort){
print("Start Timer");
lastIsolate = DateTime.now();
Timer timer = Timer.periodic(Duration(milliseconds: 20), checkTimerPeriod);
ReceivePort receivePort = ReceivePort();
sendPort.send(receivePort.sendPort);
receivePort.listen((message){
if(message is bool){
timer.cancel();
}
});
}
void checkTimerPeriod(Timer timer){
currentIsolate = DateTime.now();
Duration diff = currentIsolate.difference(lastIsolate);
if(diff.inMilliseconds > 30){
isolateCounter++;
print("${DateTime.now()}] Isolate :: ${diff.inMilliseconds}, $isolateCounter times");
}
lastIsolate = currentIsolate;
}
void main() {
ensureInitializedForSharedPreference();
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft,DeviceOrientation.landscapeRight]) ;
runApp(MyApp());
}
void ensureInitializedForSharedPreference(){
WidgetsFlutterBinding.ensureInitialized() ;
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp>{
Isolate isolate;
ReceivePort _receivePort = ReceivePort();
DateTime _lastTimer;
DateTime _currentTimer;
DateTime _lastMetronome;
DateTime _currentMetronome;
Timer timer;
StreamSubscription<DateTime> metronome;
int timerCounter;
int metronomeCounter;
@override
void initState() {
super.initState();
timerCounter = 0;
metronomeCounter = 0;
startTimers();
spawnIsolate();
}
void startTimers(){
_lastTimer = DateTime.now();
_lastMetronome = DateTime.now();
timer = Timer.periodic(Duration(milliseconds: 20), timerCheck) ;
metronome = Metronome.epoch(aMillisecond * 20).listen((event) {
metronomeCheck();
});
}
void timerCheck(Timer timer){
_currentTimer = DateTime.now();
Duration diff = _currentTimer.difference(_lastTimer);
if(diff.inMilliseconds > 30){
timerCounter++;
print("${DateTime.now()}] Timer :: ${diff.inMilliseconds}, $timerCounter times");
}
_lastTimer = _currentTimer;
}
void metronomeCheck(){
_currentMetronome = DateTime.now();
Duration diff = _currentMetronome.difference(_lastMetronome);
if(diff.inMilliseconds > 30){
metronomeCounter++;
print("${DateTime.now()}] Metronome :: ${diff.inMilliseconds}, $metronomeCounter times");
}
_lastMetronome = _currentMetronome;
}
void spawnIsolate() async {
isolate = await Isolate.spawn(timerTest, _receivePort.sendPort);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
debugShowCheckedModeBanner: false,
home: TimerTestPage()
//      home: MyHomePage(),
);
}
}

class TimerTestPage extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return TimerTestPageState();
}
}
class TimerTestPageState extends State<TimerTestPage>{
@override
Widget build(BuildContext context) {
return Container();
}
}

打印结果:

I/flutter (11728): 2020-11-18 18:00:54.002557] Metronome :: 99, 2 times
I/flutter (11728): 2020-11-18 18:00:54.002805] Timer :: 91, 2 times
I/flutter (11728): 2020-11-18 18:00:54.137470] Timer :: 45, 3 times
I/flutter (11728): 2020-11-18 18:00:54.137680] Metronome :: 35, 3 times
I/flutter (11728): 2020-11-18 18:00:54.456208] Metronome :: 34, 4 times
I/flutter (11728): 2020-11-18 18:00:55.063127] Metronome :: 38, 5 times
I/flutter (11728): 2020-11-18 18:00:55.108351] Timer :: 37, 4 times
I/flutter (11728): 2020-11-18 18:00:55.209915] Metronome :: 67, 6 times
I/flutter (11728): 2020-11-18 18:00:55.210140] Timer :: 56, 5 times
I/flutter (11728): 2020-11-18 18:00:58.800702] Metronome :: 49, 7 times
I/flutter (11728): 2020-11-18 18:00:58.801505] Timer :: 50, 6 times
I/flutter (11728): 2020-11-18 18:00:58.845783] Isolate :: 49, 2 times
I/flutter (11728): 2020-11-18 18:00:59.838194] Timer :: 40, 7 times
I/flutter (11728): 2020-11-18 18:00:59.838950] Metronome :: 35, 8 times
I/flutter (11728): 2020-11-18 18:01:00.835309] Metronome :: 52, 9 times
I/flutter (11728): 2020-11-18 18:01:00.837709] Timer :: 44, 8 times
I/flutter (11728): 2020-11-18 18:01:01.779771] Metronome :: 37, 10 times
I/flutter (11728): 2020-11-18 18:01:02.802442] Metronome :: 59, 11 times
I/flutter (11728): 2020-11-18 18:01:02.803132] Timer :: 51, 9 times
I/flutter (11728): 2020-11-18 18:01:02.827479] Isolate :: 31, 3 times
I/flutter (11728): 2020-11-18 18:01:03.800940] Metronome :: 52, 12 times
I/flutter (11728): 2020-11-18 18:01:03.801845] Timer :: 49, 10 times
I/flutter (11728): 2020-11-18 18:01:03.835860] Isolate :: 39, 4 times
I/flutter (11728): 2020-11-18 18:01:04.860201] Timer :: 66, 11 times
I/flutter (11728): 2020-11-18 18:01:04.860752] Metronome :: 57, 13 times
I/flutter (11728): 2020-11-18 18:01:04.871719] Isolate :: 35, 5 times
I/flutter (11728): 2020-11-18 18:01:05.797080] Metronome :: 54, 14 times
I/flutter (11728): 2020-11-18 18:01:05.798653] Timer :: 46, 12 times
I/flutter (11728): 2020-11-18 18:01:06.798412] Metronome :: 51, 15 times
I/flutter (11728): 2020-11-18 18:01:06.799347] Timer :: 47, 13 times
I/flutter (11728): 2020-11-18 18:01:07.802850] Metronome :: 52, 16 times
I/flutter (11728): 2020-11-18 18:01:07.803528] Timer :: 52, 14 times
I/flutter (11728): 2020-11-18 18:01:07.832428] Isolate :: 36, 6 times
I/flutter (11728): 2020-11-18 18:01:08.798311] Metronome :: 56, 17 times
I/flutter (11728): 2020-11-18 18:01:08.802467] Timer :: 50, 15 times
I/flutter (11728): 2020-11-18 18:01:09.810389] Timer :: 58, 16 times
I/flutter (11728): 2020-11-18 18:01:09.811026] Metronome :: 48, 18 times
I/flutter (11728): 2020-11-18 18:01:09.835066] Isolate :: 38, 7 times
I/flutter (11728): 2020-11-18 18:01:10.810530] Metronome :: 65, 19 times
I/flutter (11728): 2020-11-18 18:01:10.812136] Timer :: 60, 17 times
I/flutter (11728): 2020-11-18 18:01:10.830197] Isolate :: 34, 8 times
I/flutter (11728): 2020-11-18 18:01:11.810372] Timer :: 48, 18 times
I/flutter (11728): 2020-11-18 18:01:11.810956] Metronome :: 48, 20 times
I/flutter (11728): 2020-11-18 18:01:11.826718] Isolate :: 31, 9 times
I/flutter (11728): 2020-11-18 18:01:12.802337] Timer :: 50, 19 times
I/flutter (11728): 2020-11-18 18:01:12.810522] Metronome :: 47, 21 times
I/flutter (11728): 2020-11-18 18:01:12.841223] Isolate :: 44, 10 times
I/flutter (11728): 2020-11-18 18:01:13.631729] Timer :: 36, 20 times
I/flutter (11728): 2020-11-18 18:01:13.801782] Metronome :: 58, 22 times
I/flutter (11728): 2020-11-18 18:01:13.802542] Timer :: 50, 21 times
I/flutter (11728): 2020-11-18 18:01:13.835463] Isolate :: 39, 11 times
I/flutter (11728): 2020-11-18 18:01:14.789602] Timer :: 35, 22 times
I/flutter (11728): 2020-11-18 18:01:15.754015] Metronome :: 31, 23 times
I/flutter (11728): 2020-11-18 18:01:15.811248] Isolate :: 35, 12 times
I/flutter (11728): 2020-11-18 18:01:16.753175] Timer :: 36, 23 times
I/flutter (11728): 2020-11-18 18:01:16.787876] Metronome :: 33, 24 times
I/flutter (11728): 2020-11-18 18:01:16.791421] Timer :: 34, 24 times
I/flutter (11728): 2020-11-18 18:01:17.839036] Metronome :: 55, 25 times
I/flutter (11728): 2020-11-18 18:01:17.842928] Timer :: 51, 25 times
I/flutter (11728): 2020-11-18 18:01:17.871998] Isolate :: 35, 13 times
I/flutter (11728): 2020-11-18 18:01:18.804048] Timer :: 52, 26 times
I/flutter (11728): 2020-11-18 18:01:18.804922] Metronome :: 41, 26 times
I/flutter (11728): 2020-11-18 18:01:18.836156] Isolate :: 39, 14 times
I/flutter (11728): 2020-11-18 18:01:19.796440] Metronome :: 45, 27 times
I/flutter (11728): 2020-11-18 18:01:19.797077] Timer :: 45, 27 times
I/flutter (11728): 2020-11-18 18:01:20.755218] Metronome :: 31, 28 times
I/flutter (11728): 2020-11-18 18:01:20.794793] Timer :: 37, 28 times
I/flutter (11728): 2020-11-18 18:01:20.798211] Metronome :: 36, 29 times
I/flutter (11728): 2020-11-18 18:01:21.803089] Metronome :: 59, 30 times
I/flutter (11728): 2020-11-18 18:01:21.803601] Timer :: 51, 29 times
I/flutter (11728): 2020-11-18 18:01:22.283024] Timer :: 32, 30 times
I/flutter (11728): 2020-11-18 18:01:22.755033] Metronome :: 31, 31 times
I/flutter (11728): 2020-11-18 18:01:22.790614] Metronome :: 35, 32 times
I/flutter (11728): 2020-11-18 18:01:22.794945] Timer :: 38, 31 times
I/flutter (11728): 2020-11-18 18:01:22.815671] Isolate :: 39, 15 times
I/flutter (11728): 2020-11-18 18:01:23.163503] Timer :: 31, 32 times
I/flutter (11728): 2020-11-18 18:01:23.795069] Metronome :: 51, 33 times
I/flutter (11728): 2020-11-18 18:01:23.795837] Timer :: 43, 33 times
I/flutter (11728): 2020-11-18 18:01:23.841426] Isolate :: 43, 16 times
I/flutter (11728): 2020-11-18 18:01:24.795185] Metronome :: 49, 34 times
I/flutter (11728): 2020-11-18 18:01:24.795927] Timer :: 44, 34 times
I/flutter (11728): 2020-11-18 18:01:25.804665] Timer :: 52, 35 times
I/flutter (11728): 2020-11-18 18:01:25.805359] Metronome :: 41, 35 times
I/flutter (11728): 2020-11-18 18:01:25.831298] Isolate :: 35, 17 times
I/flutter (11728): 2020-11-18 18:01:26.806900] Metronome :: 39, 36 times
I/flutter (11728): 2020-11-18 18:01:26.807681] Timer :: 35, 36 times
I/flutter (11728): 2020-11-18 18:01:26.832718] Isolate :: 36, 18 times

来自Timer.periodic文档:

确切的定时取决于底层定时器的实现。在持续时间*n时间内不会进行超过n次回调,但两次连续回调之间的时间可能比持续时间更短或更长。

dart中的Timer并不像您预期的那样准确。

@Lee3的答案是绝对正确的。Timer.periodical按设计工作。但是,如果你需要使用Timer.periodic,以便在一致的tickrate方面更可靠地工作,请查看这个小软件包:reliable_periodic_Timer。

它在引擎盖下使用Timer.periodical,但根据当前毫秒检查是否已经是正确的点火时间。

它是这样使用的:

ReliableIntervalTimer(
interval: Duration(milliseconds: 100),
callback: (elapsedMilliseconds) => print('elapsedMilliseconds: $elapsedMilliseconds');,
);

最新更新