spawn<T> method

Future<CombineInfo> spawn<T>(
  1. IsolateEntryPoint<T> entryPoint, {
  2. T? argument,
  3. bool errorsAreFatal = true,
  4. String? debugName = "combine_isolate",
  5. RootIsolateToken? isolateToken,
})

Creates a new CombineIsolate which is just a representation of Isolate that allows to use MethodChannels and BinaryMessengers in it. So when you create a CombineIsolate, an Isolate will be created under the hood. On the web, however, entryPoint will be executed on the main isolate.

entryPoint is a function which will be called in Isolate. This function may be first-level, as well as a top-level or static. Also it may use closure variables but with some restrictions:

  • closure variable will be copied (as every variable passed to isolate) so it won't be synchronized across Isolates.
  • if you use at least one variable from closure all closure variables will be copied to the Isolate due to this issue. It can lead to high memory consumption or event exception because some variables may contains native resources.

Due to above points, I highly recommend you to avoid using closure variables, until this issue is fixed.

debugName is the Isolate's name for dev tools.

If errorsAreFatal is set to true then uncaught exceptions will kill the Isolate.

Returns CombineInfo which holds CombineIsolate to control Isolate and IsolateMessenger to communicate with it.

Example usage:

CombineInfo isolateInfo = await Combine().spawn((context) {
  print("Argument from main isolate: ${context.argument}");

  context.messenger.messages.listen((message) {
    print("Message from main isolate: $message");
    context.messenger.send("Hello from isolate!");
  });
}, argument: 42);

isolateInfo.messenger
  ..messages.listen((message) {
    print("Message from isolate: $message");
  })
  ..send("Hello from main isolate!");

// Will print:
// Argument from main isolate: 42
// Message from main isolate: Hello from main isolate!
// Message from isolate: Hello from isolate!

isolateToken is used to work with MethodChannels in isolate. RootIsolateToken.instance is used by default if isolate is spawned in UI isolate. If Combine isolate is spawned in another Combine isolate, it will inherit isolateToken. So isolateToken should be provided only when this method is called from NON UI isolate.

Implementation

Future<CombineInfo> spawn<T>(
  IsolateEntryPoint<T> entryPoint, {
  T? argument,
  bool errorsAreFatal = true,
  String? debugName = "combine_isolate",
  RootIsolateToken? isolateToken,
}) async {
  return effectiveIsolateFactory.create(
    entryPoint,
    argument: argument,
    errorsAreFatal: errorsAreFatal,
    debugName: debugName,
    isolateToken: isolateToken ?? getRootIsolateToken(isWeb: kIsWeb),
  );
}