What is the best way to track the state of an Isolate in Dart?

本小妞迷上赌 提交于 2019-12-06 12:25:08
Ivan Posva

If you want to make absolutely sure that you can install onExit and onError listeners in an isolate before any of the isolate's code executes, then you can spawn the isolate paused. See documentation about spawnUri.

Here is an example:

var isolate = await Isolate.spawnUri(myUri, args, message, paused: true);
var receivePort = new ReceivePort();
isolate.addOnExitListener(receivePort.sendPort);

receivePort.listen((message){
  if (message == null) { // A null message means the isolate exited
    print("Item exited: ${item.name}");
    item.status = "stopped";
  }
});

isolate.resume(isolate.pauseCapability);

Once you have registered the appropriate listeners, you can start the newly created isolate with resume.

This is very similar to the suggestion of an initial handshake, but in this case it is builtin to the library.


Hope this helps,

-Ivan

I had the same behavior when the isolate didn't do anything notable (just one print statement). It seems it exited before the onExitListener was registered.

DartDoc of onExitListener says

  • If the isolate is already dead, no message will be sent.

The isolate code

import 'dart:async' show Future, Stream;

void main(List<String> args) {
  new Future.delayed(new Duration(milliseconds: 500), 
      () =>print('isolate ${args}'));
}

With the additional delay I got the desired on exit notification. The delay needs to be quite high :-(.

You can do some initial handshake to ensure the isolate doesn't exit before everything is set up properly

import 'dart:isolate';
import 'dart:async' show Future, Stream, Completer;
import 'dart:io' as io;

class Item {
  String name;
  String status;
  Item(this.name);
}

void main() {
  final items = {'a': new Item('a'), 'b': new Item('b'), 'c': new Item('c')};
  items.forEach((name, item) async {
    ReceivePort receivePort = new ReceivePort();
    SendPort sendPort = receivePort.sendPort;
    Isolate isolate = await Isolate.spawnUri(
        Uri.parse('isolate.dart'), [sendPort, name], null);
    receivePort.listen((message) {
      if (message is SendPort) {
        message.send('connected');
      } else if (message == null) {
        print("Item exited: ${item.name}");
        item.status = "stopped";
      } else {
        print("Message: ${message}");
      }
    });
    isolate.addOnExitListener(receivePort.sendPort);
    item.status = "running";
  });
}
import 'dart:isolate';

void main(List<String> args) {
  SendPort sendPort = (args[0] as SendPort);
  var receivePort = new ReceivePort();
  sendPort.send(receivePort.sendPort);
  // keeps the isolate alive at least until the first messgae arrives
  receivePort.first.then((e) => print('isolate received: $e'));
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!