簡體   English   中英

如何從 dart 隔離中獲取多條消息?

[英]How can I get multiple messages from dart isolate?

如何從 dart 隔離中獲取多條消息?

我正在嘗試create an excel file ,並希望在該文件上執行some operation isolate 在對該文件進行操作之前,我想向主隔離返回一條消息,即創建了 excel 文件。

這是 function 進入isolate

foo(String filePath){
    // create excel file
    var bytes = File(filePath).readAsBytesSync();
    var excel = Excel.decodeBytes(bytes);

    //HERE I WANT TO SEND THE MESSAGE THAT CREATING EXCEL FILE IS DONE

    // some operatoin on excel file
    var result = doSomeOperation(excel);
    return result;
}

主要隔離代碼:

var result = await compute(foo, filePath);

在實際結果出現之前,我應該怎么做才能創建文件消息?

對於 excel,我使用的是excel:^2.0.0-null-safety-3 package。

Compute 只返回一個結果。 如果您想將多個“事件”傳遞回主隔離,那么您需要使用完整的隔離邏輯(使用 sendPort 和 receivePort)。

例如,以下代碼在隔離中運行,並下載文件,同時發出表示進度的float值,可能是表示日志消息的String ,然后是表示完成時成功或失敗的bool

  Future<void> isolateDownload(
      DownloadRequest request) async {
    final sendPort = request.sendPort;
    if (sendPort != null) {
      var success = false;
      var errorMessage = '';
      var url = Uri.parse('a_url_based_on_request');
      IOSink? out;
      try {
        http.StreamedResponse response =
            await http.Client().send(http.Request('GET', url));
        if (response.statusCode == 200) {
          var filePath =
              join(request.destinationDirPath, '${request.fileName}.ZIP');
          var contentLength = response.contentLength;
          var bytesLoadedUpdateInterval = (contentLength ?? 0) / 50;
          var bytesLoaded = 0;
          var bytesLoadedAtLastUpdate = 0;
          out = File(filePath).openWrite();
          await response.stream.forEach((chunk) {
            out?.add(chunk);
            bytesLoaded += chunk.length;
            // update if enough bytes have passed since last update
            if (contentLength != null &&
                bytesLoaded - bytesLoadedAtLastUpdate >
                    bytesLoadedUpdateInterval) {
              sendPort.send(bytesLoaded / contentLength);
              bytesLoadedAtLastUpdate = bytesLoaded;
            }
          });
          success = true;
          if (contentLength != null) {
            sendPort.send(1.0); // send 100% downloaded message
          }
        } else {
          errorMessage =
              'Download of ${request.chartType}:${request.chartName} '
              'received response ${response.statusCode} - ${response.reasonPhrase}';
        }

      } catch (e) {
        errorMessage = 'Download of ${request.chartType}:${request.chartName} '
            'received error $e';
      } finally {
        await out?.flush();
        await out?.close();
        if (errorMessage.isNotEmpty) {
          sendPort.send(errorMessage);
        }
        sendPort.send(success);
      }
    }
  }

產生隔離的代碼然后簡單地檢查傳遞給它的消息的類型以確定操作。

  Future<bool> _downloadInBackground(
      DownloadRequest request) async {
    var receivePort = ReceivePort();
    request.sendPort = receivePort.sendPort;
    var isDone = Completer();
    var success = false;
    receivePort.listen((message) {
      if (message is double) {
        showUpdate(message);
      }
      if (message is String) {
        log.fine(message); // log error messages
      }
      if (message is bool) {
        success = message; // end with success or failure
        receivePort.close();
      }
    }, onDone: () => isDone.complete()); // wraps up
    await Isolate.spawn(isolateDownload, request);
    await isDone.future;
    return success;
  }

暫無
暫無

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

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