0

The below program is for understanding isolates in dart. The compute method is passed to the spawned isolate. Inside of compute method summation is performed but when List.generate is used the compute function doesn't finish the execution because the print("The total sum is : $sum"); statement is never called.

Instead of using List.generate if we use simple for loop (commented line of code in compute()) the sum is calculated and also displayed.

import "dart:isolate";

void main(final List<String> args) async {
  print("Entering main");
  final model = ModelClass(35000, 100);
  await Isolate.spawn<ModelClass>(compute, model);
  print("Exiting main");
}

void compute(final ModelClass model) {
  int sum = 0;
  for (int value in List.generate(model.iteration, (index) => index)) {
    sum += value * model.multiplier;
  }
  // for (int index = 0; index < model.iteration; index++) {
  //   sum += index * model.multiplier;
  // }
  print("The total sum is : $sum");
}

class ModelClass {
  final int iteration;
  final int multiplier;

  ModelClass(this.iteration, this.multiplier);
}

Why when we use List.generate to generate a list and iterate over it the compute function doesn't finish execution?

Udesh
  • 2,415
  • 2
  • 22
  • 32
  • 1
    I'm not an expert on Dart isolates, but I think that this is simply because the version with the basic `for`-loop is faster than the `List.generate` version, so it manages to complete before the program terminates. As written, I don't think that the main isolate will wait for the spawned isolate to complete. I think that you can observe the `compute` function completing if you add a delay before exiting `main`. – jamesdlin Apr 16 '23 at 07:30
  • 2
    Correct. The program ends when the main isolate exits. It does that after printing "Exiting main". The other isolate dies with it, after having done some, but not necessarily all, of its work. – lrn Apr 16 '23 at 19:05

1 Answers1

3

Your problem is that the following does not await the spawned Isolate being done executing. Instead, it will just await on the creation of the Isolate itself.

await Isolate.spawn<ModelClass>(compute, model);

After this, your main Isolate have nothing else to do and does not have any way to later get triggered by any kind of event (e.g. from RecievePort, Timer or similar).

Dart will therefore quit your program since your programs execution is only depended on the mail Isolate. See the following answer for a more detailed description of when Dart programs stops and does not stop: https://stackoverflow.com/a/70670962/1953515

But in short, you need to make your main Isolate wait for some answer back from your spawned isolates if you want your program to first being stopped after all isolates are done execution.

The compute() function in Flutter is doing that since it is designed to run a given function in a separate Isolate and then return the result back to the caller isolate. So it will automatically setup a RecievePort/SendPort pair.

In Dart, you can do the same with the newly introduced Isolate.run introduced in Dart 2.19: https://api.dart.dev/stable/2.19.6/dart-isolate/Isolate/run.html

julemand101
  • 28,470
  • 5
  • 52
  • 48