Ist es möglich, wiederholte Senden/Antworten zu demselben Dart-Isolat innerhalb einer einzigen asynchronen Funktion einzukapseln?verkapselte wiederholte Senden/Antworten an das gleiche Dart-Isolat innerhalb einer einzigen asynchronen Funktion
Hintergrund:
Um eine günstige API zu entwerfen, würde Ich mag eine Funktion asynchron das Ergebnis mit einem Isolat erzeugte Rückkehr haben, z.B.
var ans = await askIsolate(isolateArgs);
Dies funktioniert gut, wenn ich direkt die durch einen Aufruf spawnUri erzeugte Antwort verwenden, zB
Future<String> askIsolate(Map<String,dynamic> isolateArgs) {
ReceivePort response = new ReceivePort();
var uri = Uri.parse(ISOLATE_URI);
Future<Isolate> remote = Isolate.spawnUri(uri, [JSON.encode(isolateArgs)], response.sendPort);
return remote.then((i) => response.first)
.catchError((e) { print("Failed to spawn isolate"); })
.then((msg) => msg.toString());
}
Der Nachteil des obigen Ansatzes ist jedoch, dass, wenn ich brauche askIsolate wiederholt zu nennen, die Isolat muss jedes Mal hervorgebracht werden.
Ich möchte stattdessen mit einem laufenden Isolat kommunizieren, was sicherlich möglich ist, indem das Isolat einen sendPort an den Aufrufer zurückgibt. Aber ich glaube, seit dem 2013 Isolate refactoring erfordert dies, dass der Anrufer nachfolgende Nachrichten auf dem Empfangsanschluss abhören muss, was eine Kapselung innerhalb einer einzigen asynchronen Funktion unmöglich macht.
Gibt es einen Mechanismus, um dies zu erreichen, die ich vermisse?
Es ist ein, während ich mit Isolaten gespielt. https://pub.dartlang.org/packages/isolate soll eine nette API zum Isolieren bereitstellen. Ich nehme an, es lohnt sich, genauer hinzusehen. –
Der 'IsolateRunner' in' package: isolate' ist zum mehrmaligen Aufruf einer Funktion in einem erzeugten Isolat vorgesehen. Ich denke, es wird für dieses Problem funktionieren: 'var runner = warten IsolateRunner.spawn(); for (var arg in etwas)} {... aware runner.run (queryFunction, arg); ...} awarner runner.close(); ' – lrn
Eine weitere Möglichkeit besteht darin, dass ein Service-Isolat ausgeführt wird, aber anstatt das Ergebnis jedes Mal an denselben Port zurückgeben zu müssen, kann jede Anforderung ihren eigenen SendPort senden. Dann kann jede Anfrage einen "ResponsePort" erzeugen und den "ersten" Getter davon für die Antwort zurückgeben: Zukünftige askIsolate (isolateArgs) {var p = new ReceivePort(); runningIsolatePort.send ([isolateArgs, p.sendPort]); Rückkehr p.first; } '. – lrn