从 Dart Isolates 中捕获异常

Catching Exceptions from Dart Isolates

我在弄清楚如何从 isolates 中捕获异常时遇到了问题。使用以下代码,我已经尝试了所有我能想到的来处理从 task 抛出的错误,但它仍然被标记为 Unhandled exception.

void main() async {
  try {
    var rp = ReceivePort();

    rp.listen((message) {
      print(message);
    }, onError: (e) {
      print(e);
    });
    rp.handleError((e) {
      print(e);
    });
    var isolate = await Isolate.spawn(task, rp.sendPort);
    isolate.addErrorListener(rp.sendPort);
  } catch (e) {
    print(e);
  }
}

void task(SendPort sp) {
  sp.send('hello from isolate');
  throw Exception();
}

我在这里错过了什么?

编辑:从下面的答案来看,我的解决方案应该是这样的:

void main() async {
  var rp = ReceivePort();
  var errorRp = ReceivePort();
  errorRp.listen((e) {
    print('exception occured');
    print(e);
  });
  rp.listen(print);
  await Isolate.spawn(task, rp.sendPort, onError: errorRp.sendPort);
  await Future.delayed(Duration(seconds: 1));
  rp.close();
  errorRp.close();
}

void task(SendPort sp) {
  sp.send('hello from isolate');
  throw Exception();
}

我认为您错过了 Isolate.spawn 文档的重要部分:

You can also call the setErrorsFatal, addOnExitListener and addErrorListener methods on the returned isolate, but unless the isolate was started as paused, it may already have terminated before those methods can complete.

你的问题是你生成的 Isolate 在你的 isolate.addErrorListener(rp.sendPort); 执行之前已经执行了 throw Exception()

相反,做这样的事情来生成 Isolatepaused 然后稍后 resume 它:

    var isolate = await Isolate.spawn(task, rp.sendPort, paused: true);
    isolate.addErrorListener(rp.sendPort);
    isolate.resume(isolate.pauseCapability!);

或者,您可以将 Isolate 错误处理程序作为生成的一部分:

var isolate = await Isolate.spawn(task, rp.sendPort, onError: rp.sendPort);