如何從 dart 隔離中獲取多條訊息?
我正在嘗試create an excel file并希望some operation在隔離中對該檔案進行處理。在對該檔案進行操作之前,我想向主隔離回傳一條訊息,即創建該 excel 檔案。
這是功能進入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包。
uj5u.com熱心網友回復:
Compute 只回傳一個結果。如果您想將多個“事件”傳遞回主隔離,那么您需要使用完整的隔離邏輯(使用 sendPort 和 receivePort)。
例如,以下代碼在隔離中運行,并下載檔案同時發出float表示進度的值,可能 aString表示日志訊息,然后 abool表示完成后的成功或失敗。
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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/386114.html
