๐ŸŽ“ A1Learner
๐Ÿ”
0 of 24 lessons completed

Dart Isolate Run

Isolate.run runs a closure on a fresh isolate and returns a future for its result. The result crosses back to the waiting code when the closure finishes.

A total computed on another isolate

The closure adds the five numbers on a fresh isolate. The awaited result prints as one total line.

import 'dart:isolate';

Future<void> main() async {
  var total = await Isolate.run(() {
    var sum = 0;
    for (var n in [1, 2, 3, 4, 5]) {
      sum = sum + n;
    }
    return sum;
  });
  print('total $total');
}

A record crosses back as the result

The closure returns a record holding a name and an age. The record crosses the boundary whole, and its fields print on one line.

import 'dart:isolate';

Future<void> main() async {
  var person = await Isolate.run(() => ('ada', 36));
  print('${person.$1}: ${person.$2}');
}

An error crosses back intact

The closure throws a StateError with the message kaput. The error crosses back, and the typed catch prints it with the message unchanged.

import 'dart:isolate';

Future<void> main() async {
  try {
    await Isolate.run(() => throw StateError('kaput'));
  } on StateError catch (e) {
    print('StateError: ${e.message}');
  }
}

A thrown string arrives as a String

The closure throws a plain string instead of an error object. The catch reads the runtime type of the value that arrives, and it is String.

import 'dart:isolate';

Future<void> main() async {
  try {
    await Isolate.run(() => throw 'plain text');
  } catch (e) {
    print(e.runtimeType);
    print(e);
  }
}

Example

import 'dart:async';
import 'dart:isolate';

int square(int n) => n * n;

Future<void> main() async {
  var results = await Future.wait([
    Isolate.run(() => square(3)),
    Isolate.run(() => square(4)),
  ]);
  print(results[0]);
  print(results[1]);
  print(results);
}

Key points

  • Isolate.run starts its work on a separate isolate, away from the main isolate.
  • Awaiting the returned future gives the value the closure returned.
  • Values that cross the isolate boundary are copied, and a record can cross as a result.
  • An error thrown inside the closure crosses back as an error, and a typed catch can catch it with its message intact.
  • A value thrown as a plain string crosses back as a String.

In this example, two Isolate.run computations run under one Future.wait, one squaring 3 and one squaring 4. The results print in the order of the wait list, first 9 and then 16, and the full list prints last.

Note

Isolate.run suits a single self contained computation that returns one result.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท DartPad

Exercise

What does awaiting Isolate.run give when its closure throws a StateError?