Why streams in Dart isolates doesn't work without receive port

Issue

I have a strange problem when i try to use a stream inside an isolate,
if i try something like this

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;
}

nothing is printed into the console , but if i add a receive port inside the main method it works fine
,even if i don’t use the receive port

 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

is this a bug or i have something wrong ?

Solution

The problem in you first example is you are not waiting for the isolate to be done in your main thread/isolate. Dart quits when the main thread/isolate do not have anything to do and the event queue are empty.

In you next example it “works” but what you are not telling is that the program never quits. That is because you have created a ReceivePort with no listener which prevents the main thread/isolate to stop since it now waits forever.

If you instead uses the ReceivePort in this way you can use it to wait for the isolate to be done and only exit the main loop when that happen:

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;
  }
}

Answered By – julemand101

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *