【发布时间】:2016-04-08 12:56:36
【问题描述】:
是否可以在单个异步函数中封装对同一个 dart 隔离的重复发送/响应?
背景:
为了设计一个方便的API,我想让一个函数异步返回一个isolate生成的结果,例如
var ans = await askIsolate(isolateArgs);
如果我直接使用 spawnUri 调用生成的响应,这可以正常工作,例如
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());
}
但是,上述方法的缺点是,如果我需要重复调用 askIsolate,则每次都必须生成隔离。
我想与一个正在运行的隔离通信,这当然可以通过让隔离返回一个 sendPort 给调用者来实现。但我相信自从2013 Isolate refactoring 以来,这需要调用者在receivePort 上监听后续消息,从而无法在单个异步函数中进行封装。
是否有一些我缺少的机制来完成这个?
【问题讨论】:
-
我有段时间玩孤立的。 pub.dartlang.org/packages/isolate 应该为隔离提供一个很好的 API。我认为值得仔细研究一下。
-
IsolateRunner中的package:isolate用于多次调用衍生隔离中的函数。我认为它可以解决这个问题:var runner = await IsolateRunner.spawn(); for (var arg in something) }{ ... await runner.run(queryFunction, arg); ... } await runner.close(); -
另一种选择是让服务隔离运行,但不是让它每次都在同一个端口上返回结果,而是每个请求都可以发送自己的
SendPort。然后每个请求都可以创建一个ResponsePort并返回firstgetter 作为响应:Future askIsolate(isolateArgs) { var p = new ReceivePort(); runningIsolatePort.send([isolateArgs, p.sendPort]); return p.first; }。 -
我没有成功让 IsolateRunner 在 spawnURI 情况下正常工作。我需要能够在外部 dart 脚本上调用和执行已知方法。我知道您可以使用 IsolateRunner 手动包装 Isolate,但我没有看到如何利用 IsolateRunner.run 来执行外部方法。但是,lrn 的第二个建议似乎效果很好。我将完成一些测试并发布一个完整的示例
标签: dart dart-isolates