Почему потоки в изолятах Dart не работают без порта приема - PullRequest
1 голос
/ 08 октября 2019

У меня странная проблема, когда я пытаюсь использовать поток внутри изолята, если я пытаюсь что-то вроде этого

main() async {
  await Isolate.spawn(entryPoint, null);
}

entryPoint(SendPort sendPort) {
  getStreamOfNumbers().listen((data) => print('data : $data'));
}

Stream<int> getStreamOfNumbers() async* {
  for (int x = 0; x < 10; x++) yield x;
}

, в консоль ничего не выводится, но если я добавляю порт приема внутриОсновной метод работает нормально, даже если я не использую порт приема

 main() async {
  ReceivePort receivePort = ReceivePort();
  await Isolate.spawn(entryPoint, null);
}

//the output is : 
//data : 0
//data : 1
//data : 2
//data : 3
//data : 4
//data : 5
//data : 6
//data : 7
//data : 8
//data : 9

Это ошибка или у меня что-то не так?

1 Ответ

1 голос
/ 08 октября 2019

Проблема в первом примере заключается в том, что вы не ждете, когда будет сделан изолят в вашем основном потоке / изоляте. Дротик завершается, когда основной поток / изолят не имеют ничего общего и очередь событий пуста.

В следующем примере это «работает», но вы не говорите, что программа никогда не завершает работу. Это связано с тем, что вы создали ReceivePort без прослушивателя, который не позволяет основному потоку / изоляту остановиться, поскольку он теперь ожидает вечно.

Если вместо этого вы используете ReceivePort таким образом, вы можете использовать его для ожидания изолятадолжно быть сделано и выходить из основного цикла только тогда, когда это произойдет:

import 'dart:isolate';

Future<void> main() async {
  final rPort = ReceivePort();
  await Isolate.spawn(entryPoint, null, onExit: rPort.sendPort);
  await rPort.first;
}

void entryPoint(SendPort sendPort) {
  getStreamOfNumbers().listen((data) => print('data : $data'));
}

Stream<int> getStreamOfNumbers() async* {
  for (var x = 0; x < 10; x++) {
    yield x;
  }
}
...