是否可以为Dart Isolates提供多个发送和接收端口?

时间:2012-09-17 12:19:52

标签: dart dart-isolates

是否可以在Dart中为同一个Isolate打开多个发送和接收端口?

E.g。下面的代码示例将创建两个隔离区,每个隔离区都有自己的发送端口。但是,我想知道是否有任何方法可以为同一个隔离区创建多个发送/接收端口,并选择接收端口来发送消息。

    #import('dart:isolate');

    echo() {

    }

    main() {
        var sendPort1 = spawnFunction(echo);
        var sendPort2 = spawnFunction(echo);
    }

3 个答案:

答案 0 :(得分:3)

你实际上可以创建任意数量的ReceivePort,然后就像Matt所说,每个ReceivePort有任意数量的SendPort。

默认情况下,隔离区(包括主隔离区)已创建一个ReceivePort,可通过port getter获得。此ReceivePort已连接到从spawnFunction()spawnUri()返回的SendPort。但您可以使用new ReceivePort()创建新的ReceivePort,然后您可以通过toSendPort()创建任意数量的已连接SendPort。要使用它们,您需要发送新的SendPort以及您从spawnFunction()ReceivePort.receive()获得的原始SendPort上的消息。

通过这样做,您可以在两个隔离区之间设置多个“通道”。我还没有玩过它,看看它在实践中是如何工作的,我一直在一个SendPort上通过结构化消息多路复用频道。

请注意,您可以在任何隔离中创建ReceivePort:父隔离或子隔离。因此,如果您希望partent为子项提供两个SendPort,那么您需要一个来自spawnFunction()的另一个以及另一个从子项传递回到父级的消息。

这是您的示例更改为使用多个SendPorts。步骤:

  1. main:Spawn a isolate
  2. main:使用SendPort发送消息,以便隔离区可以发回消息
  3. echo:在隔离区
  4. 中创建第二个ReceivePort
  5. echo:使用replyTo SendPort
  6. 在隔离区中接收消息
  7. echo:从ReceivePort创建一个SendPort并将其发回
  8. main:从echo
  9. 接收消息和SendPort

    现在main()有两个独立的SendPort到隔离区。

    #import('dart:isolate');
    
    echo() {
      var port2 = new ReceivePort(); // 3
    
      port2.receive((m, p) {
        print("two: $m");
      });
    
      port.receive((m, p) { // 4
        print("one: $m");
        p.send("ack", port2.toSendPort()); // 5
      });
    }
    
    main() {
      port.receive((m, sendPort2) { // 6
        sendPort2.send("hello 2");
      });
      var sendPort1 = spawnFunction(echo); // 1
      sendPort1.send("hello 1", port.toSendPort()); // 2
    }
    

    打印:

    one: hello 1
    two: hello 2
    

    呼!

答案 1 :(得分:1)

虽然我不确定多个接收端口。您可以为每个接收端口创建多个发送端口。此功能构建在ReceivePort类中:ReceivePort.toSendPort

如帮助底部所示:

  

从同一个ReceivePort创建多个SendPort是合法的。

希望这有帮助。

答案 2 :(得分:0)

Justin的答案基本上是正确的,但是由于隔离区在执行完第5步后停止响应,因此给我带来了一些麻烦。所以这是一个在我的上下文中实际工作的更新版本:

import 'dart:isolate';

echo() {
  var port2 = new ReceivePort();

  port2.receive((m, p) {
    print("two: $m");
  });

  port.receive((m, p) {
    print("one: $m");
    p.send(port2.toSendPort());
  });
}

main() {
  var sendPort1 = spawnFunction(echo);
  sendPort1.call("hello 1").then((newPort)=>newPort.send("hello 2"));
}

主要区别在于端口是作为消息发送而不是使用replyTo字段。这也允许更紧凑的代码,因为不需要其他接收端口。