[英]Timer inside flutter isolate not stopping when isolate is killed
我有一個應用程序使用 API 調用將操縱桿 position 數據上傳到網絡服務器。
移動操縱桿時調用此方法。 如果操縱桿不在中心,它將停止任何先前運行的隔離並啟動新的隔離。
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 不斷上傳操縱桿的舊位置和新位置。 我假設這是因為即使隔離被殺死,計時器也會繼續運行。
問題:
正如我在評論中指出的那樣,您的示例代碼具有:
Future<void> startIsolate() async {
stopIsolate();
isolate =
await Isolate.spawn(isolateMethod, DateTime.now().toIso8601String());
}
void stopIsolate() {
if (isolate != null) {
debugPrint("Stopping isolate");
isolate.kill();
isolate = null;
}
}
當另一個對startIsolate
的調用已經在進行中時,沒有什么能阻止startIsolate
被調用。 因此,您的問題不在於殺死隔離物並不會停止其Timer
,而是您泄漏隔離物並阻止自己殺死它們。 您需要添加一個守衛以避免在另一個創建請求正在進行時產生新的隔離。 一個bool
就足夠了:
bool isStartingIsolate = false;
Future<void> startIsolate() async {
if (isStartingIsolate) {
// An isolate is already being spawned; no need to do anything.
return;
}
stopIsolate();
isStartingIsolate = true;
try {
isolate =
await Isolate.spawn(isolateMethod, DateTime.now().toIso8601String());
} finally {
isStartingIsolate = false;
}
}
一種不同的方法,如果您想在處理任何新的之前等待掛起的startIsolate
調用完成:
Future<void> pendingStartIsolate;
Future<void> startIsolate() async {
while (pendingStartIsolate != null) {
await pendingStartIsolate;
}
stopIsolate();
try {
pendingStartIsolate =
Isolate.spawn(isolateMethod, DateTime.now().toIso8601String());
isolate = await pendingStartIsolate;
} finally {
pendingStartIsolate = null;
}
}
查看插件easy_isolate,它提供了一種簡單的方法來使用隔離已經完成的安全檢查和其他很酷的功能,還有一個很好解釋的文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.