为什么在使用 Isolates 后我们必须使用 exit(0) 退出 main?

SUN*_*AUL 2 asynchronous dart

import 'dart:io';
import 'dart:isolate';

Isolate? isolate;

void printX(SendPort sendPort) {
  print(sendPort);
}

void main() async {
  var receiverPort = ReceivePort();
  isolate = await Isolate.spawn(printX, receiverPort.sendPort);
  isolate!.kill(priority: Isolate.immediate);
  exit(0);
}
Run Code Online (Sandbox Code Playgroud)

为什么我们必须执行 exit(0) ?

我看到,如果我不使用退出代码退出,那么我就会陷入困境,就像它在等待某些输入一样。虽然隔离体被杀死了。

Mic*_*orn 6

本质上,并不是Isolate让这个过程保持活力;而是让这个过程持续下去。它实际上是ReceivePort. 它们ReceivePort并不“知道”隔离体已被杀死,因此它仍在愉快地等待事件的发生。

调用receiverPort.close()将使进程结束。事实上,从技术上讲,您甚至不需要杀死隔离来结束进程,只要您关闭流即可。

这是立即终止的代码的完整版本:

import 'dart:io';
import 'dart:isolate';

Isolate? isolate;

void printX(SendPort sendPort) {
  print(sendPort);
}

void main() async {
  var receiverPort = ReceivePort();
  isolate = await Isolate.spawn(printX, receiverPort.sendPort);
  receiverPort.close();
}
Run Code Online (Sandbox Code Playgroud)

补充说明:如果有监听器订阅了ReceivePort,并且监听器取消了订阅,则ReceivePort会自行关闭;但是,它的设计目的是缓冲传入事件,直到订阅侦听器为止 - 因此,如果没有侦听器订阅,它永远不会自行关闭。

所以这段代码也会终止:

void main() async {
  var receiverPort = ReceivePort();

  var subscription = receiverPort.listen((message) {});
  isolate = await Isolate.spawn(printX, receiverPort.sendPort);
  
  subscription.cancel();
}
Run Code Online (Sandbox Code Playgroud)