【发布时间】:2020-08-13 15:19:17
【问题描述】:
我有一个应用程序使用 API 调用将操纵杆位置数据上传到网络服务器。
当操纵杆移动时调用此方法。如果操纵杆不在中心,它将停止任何先前运行的隔离并启动新的隔离。
void onJoystickMoved(double angle, double distance) {
stopIsolate();
if(distance > 0.06){
startIsolate(JoystickPosition.fromDistanceAndRadius(distance, angle));
}
}
隔离启动和停止方法
Future<void> startIsolate(JoystickPosition position) async {
isolate = await Isolate.spawn(uploadJoystickPosition, position);
}
void stopIsolate() {
if (isolate != null) {
debugPrint("Stopping isolate");
isolate.kill();
isolate = null;
}
}
uploadJoystickPosition 方法(isolate 中的方法):
void uploadJoystickPosition(JoystickPosition position){
Timer.periodic(new Duration(seconds: 1), (Timer t) {
DataModel dataModel = DataModel(1, getTimeInSeconds());
dataModel.joystickPosition = position;
debugPrint("Distance: ${position.distance}");
uploadData(dataModel).then(uploadResponse, onError: uploadError);
});
}
问题是uploadJoystickPosition 不断上传操纵杆的旧位置和新位置。我假设这是因为即使隔离被杀死,计时器也会继续运行。
问题:
- 为什么我的计时器在我杀死隔离后仍然继续运行(并上传)?
- 当我杀死正在运行的隔离时,如何让计时器停止?
【问题讨论】:
-
你能提供一个最小的、完整的、可验证的例子吗?在 Linux 上使用 Dart VM 运行 gist.github.com/jamesderlin/29b5b34608d851531e7161703e86ccf4 时,我无法重现您的问题。
-
我从来没有单独在 Dart 上工作过,我需要这个来处理颤振。所以我做了一个简单的颤振应用程序。 github.com/Drkstr/flutter_isolate_test。单击“开始隔离”应启动一个隔离,该隔离将重复打印在控制台上启动隔离的时间。再次单击“开始隔离”应该会杀死以前的隔离并开始新的隔离。如果您单击“开始隔离”等待几秒钟,然后再次单击“开始隔离”,这可以正常工作。如果您连续快速地反复捣碎“开始隔离”,它无法杀死之前的隔离。
-
嗯,那是一个不同的问题,不是吗?那么问题不在于杀死隔离不会取消
Timer,而是您有一个无法杀死的隔离。而且由于它可以正常工作,但当您快速连续点击“开始隔离”按钮时却无法正常工作,这听起来像是您遇到了竞争状况。查看您的代码,似乎没有任何东西可以阻止调用startIsolate,而另一个对startIsolate的调用已经在进行中。因此,您最终会泄漏分离物。 -
我不知道有什么好的方法来判断一个隔离物何时被杀死。在您的示例代码中,您实际上并不需要知道;如果
isolate != null,让startIsolate什么都不做就足够了。这将防止在另一个创建请求正在进行时创建隔离。 -
我之前的评论不太正确;您无法检查
isolate != null,因为直到Future完成后才会设置isolate。请参阅下面的my answer。
标签: flutter dart dart-isolates