簡體   English   中英

flutter 內部的計時器在隔離被殺死時不會停止

[英]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 不斷上傳操縱桿的舊位置和新位置。 我假設這是因為即使隔離被殺死,計時器也會繼續運行。

問題:

  1. 為什么我的計時器在我殺死隔離后仍然繼續(並上傳)?
  2. 當我殺死正在運行的隔離時,如何讓我的計時器停止?

正如我在評論中指出的那樣,您的示例代碼具有:

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,它提供了一種簡單的方法來使用隔離已經完成的安全檢查和其他很酷的功能,還有一個很好解釋的文檔。

https://pub.dev/packages/easy_isolate

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM