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?
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