Как закрыть ReceivePort, чтобы метод .toList() работал?

Я пытаюсь получить ответ от Изолировать как список. Я написал следующий код. Проблема в том, что он не работает. Это просто ждать.

main() async
{
  ReceivePort receivePort = ReceivePort();
  Isolate.spawn(echo, receivePort.sendPort);

  var d = await receivePort.toList();
  receivePort.close();
  print(d);
}

echo(SendPort sendPort) async
{
  ReceivePort receivePort = ReceivePort();
  sendPort.send("message");
}

person Dmitry Bubnenkov    schedule 12.07.2019    source источник


Ответы (2)


receivePort — это поток. Когда вы вызываете toList в потоке, он ожидает завершения потока. Этого никогда не происходит, поэтому вызов toList останавливается навсегда.

Если вы знаете, что другой конец связи отправляет только одно сообщение, вы можете вместо этого сделать var d = await receivePort.first;. Это только ждет первого сообщения.

В общем, при изолированной связи отправляющий изолят должен отправить специальное сообщение, когда они будут завершены, потому что у принимающего изолята нет другого способа узнать об этом. То есть: вам нужен протокол связи, чтобы получатель мог знать, будут ли еще сообщения. Возможно, каждое сообщение является объектом, содержащим логическое значение isLast, или последнее сообщение имеет значение null, или вы заключаете все сообщения в подклассы класса Message, который определяет ваш протокол. Что делать, зависит от фактического варианта использования. Единственное правило: вы должны сказать, когда закончите.

person lrn    schedule 12.07.2019

Вы должны использовать .listen() вместо await for, если вы хотите увидеть вывод списка до закрытия потока. listen зарегистрирует обработчик, и выполнение продолжится.

вместо

  var d = await receivePort.toList();
  receivePort.close();
  print(d);

пытаться

receivePort.listen((data) => {print(data)});

Вы можете найти различия с прослушиванием и ожиданием ">здесь

person Gürkan Sevinc    schedule 13.08.2019