Dart隔离作为工人

Pij*_*usn 6 communication dart dart-isolates

编辑使问题更清楚.

我正在尝试使用Dart中的Isolates(或Web Workers).我可以找到在主线程和隔离线程之间进行通信的唯一方法是发送调用然后从主线程.但这是主线程将一些数据传递给隔离的好方法.

如果我希望隔离是生成信息的那个人怎么办?就像一个游戏引擎,它可以完成工作中的所有物理,然后将更新的世界信息发送到主线程?在JavaScript中,您可以随时发送数据.在达特有一种有效的方式吗?或者我是否仍然需要等待主线程给我打电话然后传递给它?

PS我想知道,是否调用然后阻止线程直到回复完成?

Set*_*add 5

从 Dart 1.0 开始,您可以像这样使用隔离:

import 'dart:isolate';
import 'dart:async';

void doStuff(SendPort sendPort) {
  print('hi from inside isolate');
  ReceivePort receivePort = new ReceivePort();
  sendPort.send(receivePort.sendPort);

  receivePort.listen((msg) {
    print('Received in isolate: [$msg]');
    sendPort.send('ECHO: $msg');
  });

}

void main() {
  SendPort sendPort;

  ReceivePort receive = new ReceivePort();
  receive.listen((msg) {
    if (sendPort == null) {
      sendPort = msg;
    } else {
      print('From isolate: $msg');
    }
  });

  int counter = 0;

  Isolate.spawn(doStuff, receive.sendPort).then((isolate) {
    new Timer.periodic(const Duration(seconds:1), (t) {
      sendPort.send('Count is ${counter++}');
    });
  });
}
Run Code Online (Sandbox Code Playgroud)


Lar*_*ann 3

警告:此代码仅适用于非常旧版本的 Dart。它不适用于 Dart 1.0 或更高版本。

正如您提到的将消息发布到隔离区,您需要拥有其发送端口的句柄。

#import('dart:isolate');

main() {
  SendPort sendPort = spawnFunction(doWork);
  sendPort.call("hey 1").then((String res) => print("result was: [$res]"));
  sendPort.call("hey 2").then((String res) => print("result was: [$res]"));
}

doWork() {
  port.receive((msg, reply) {
    msg = "msg $msg";
    reply.send(msg);
  });
}
Run Code Online (Sandbox Code Playgroud)

然而,由于 Dart 主线程本身就是一个隔离体,您可以使用全局端口函数向其发送数据:

#import('dart:isolate');
#import('dart:io');

main() {
   port.receive((data, reply) {
       // in here you can access objects created in the main thread
       print("handle [${data['text']}] for index ${data['index']}");
   });

   SendPort workPort = spawnFunction(doWork);
   workPort.send("msg", port.toSendPort());
}

doWork() {
   port.receive((msg, reply) {
      int i = 0;
      new Timer.repeating(1000, (Timer timer) {
         i++;
         var data = {
            "text": "$msg $i",
            "index": i
         };
         print("sending $data");
         reply.send(data);
      });
   });
}
Run Code Online (Sandbox Code Playgroud)

请注意,隔离区之间可以来回发送的内容存在一定的限制,而且当前隔离区在 JS 和 VM 上的行为也不同。这里很好地描述了当前的限制。

  • 计时器现在位于 dart:isolate 中,而不是位于 dart:io 中。 (2认同)