Why doesn't the isolate receive the stop message?

Issue

The UI shows two button: One button to start an isolate, and a second button to stop it at next occasion.
The UI (widget) code looks like this:

SendPort sendToIsolatePort;

void _onStartIsolateButtonPushed() async {
  ReceivePort receivePort = ReceivePort();
  receivePort.listen(onMessageReceivedFromIsolate);
  Isolate.spawn(runAsIsolate, receivePort.sendPort);
}

void _onStopIsolateButtonPushed() async {
  sendToIsolatePort.send("Stop");
}

void onMessageReceivedFromIsolate(var message) {
  if (message is String) {
    print("Message received from isolate: " + message);
  } else if (message is SendPort) {
    print("Reply port received");
    sendToIsolatePort = message;
    sendToIsolatePort.send("Hello World?!?");
  }
}

The code in isolate.dart looks like this:
(Note: this one’s not in a widget or class, just some global functions)

import 'dart:isolate';

SendPort sendPort;
bool isRunning;

void runAsIsolate(SendPort port) async {
  sendPort = port;
  ReceivePort receivePort = ReceivePort();
  receivePort.listen(onIsolateMessageReceived);

  isRunning = true;
  sendPort.send(receivePort.sendPort);

  while (isRunning) {
    _doSomething();
    _doSomethingMore();
  }

  receivePort.close();
  sendPort.send("Stopped");
  print("Leaving isolate...");
}

void onIsolateMessageReceived(var message) {
  if (message is String) {
    print("Isolate: messate received: " + message);
    if (message == "Stop") {
      isRunning = false;
    }
  } else {
    print("WTFlutter... " + message.toString());
  }
}

void _doSomething() {}
void _doSomethingMore() {}

Now, for some reason, the isolate neither receives the "Hello World?!?" nor the "Stop" message. Do you have any ideas why? And how to fix it?

Also: Is there a simpler (or shorter) way of executing a thread in flutter? The isolate approach, and it’s stream communication, appear very much over-complicated for something as common as parallel execution.

Your advise is much appreciated. Thank you.

Solution

(Rephrased from the comments above, since this is the answer that solves the question.)

I see a problem: your while (isRunning) will consume all time in our main isolate. thus there is no time that your onIsolateMessageReceived can be called! Try to remove your while loop, and do this instead: while(isRunning) await Future.delayed(Duration(seconds: 1));.

As for executing a thread: No, there is nothing else. isolates are the fundamental building blocks in flutter, and that is the design – no shared memory. However, there do exist some small shortcuts. For example, have a look at: api.flutter.dev/flutter/foundation/compute.html , which is a easier way to do computations in another "thread"(isolate).

Answered By – ch271828n

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

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