无效参数:隔离消息中的非法参数:(对象是接收端口)

Invalid argument(s): Illegal argument in isolate message: (object is aReceivePort)

我不确定我是否在这段代码中做错了什么,但我在生成新的 isolate 时显然传递了 SendPort,但是当我调用时: Infrastructure.instance.initialize(); 我得到以下异常:

Invalid argument(s): Illegal argument in isolate message: (object is aReceivePort)

下面是Infrastructure的基本实现:

class Infrastructure {
  late final SendPort _sendPort;
  late final ReceivePort _receivePort; 

  Infrastructure._() {
    _receivePort = ReceivePort();
    Isolate.spawn(_processWorkItemsInBackground, _receivePort.sendPort,
        debugName: 'InfrastructureIsolate');

    _sendPort = _receivePort.first as SendPort;
  }

  Future<void> dispose() async {
    // Send a signal to the spawned isolate indicating that it should exit:
    _sendPort.send(null);
  }

  static final Infrastructure instance = Infrastructure._();

  void initialize() {}

  Future<void> _processWorkItemsInBackground(SendPort sendPort) async {
    ModuleLogger.moduleLogger.info('Infrastructure isolate started.');

    // Send a SendPort to the main isolate
    // so that it can send JSON strings to this isolate:
    final commandPort = ReceivePort();
    sendPort.send(commandPort.sendPort);

    // Wait for messages from the main isolate.
    await for (final message in commandPort) {
      // cast the message to one of the expected message types,
      // handle it properly, compile a response and send it back via
      // the sendPort if needed.
      // For example,
      if (message is String) {
        // Read and decode the file.
        final contents = await File(message).readAsString();

        // Send the result to the main isolate.
        sendPort.send(jsonDecode(contents));
      } else if (message == null) {
        // Exit if the main isolate sends a null message, indicating there are no
        // more files to read and parse.
        break;
      }
    }

    ModuleLogger.moduleLogger.info('Infrastructure isolate finished.');
    Isolate.exit();
  }
}

实际上我大约一个月前为类似问题开了一张工单:

https://github.com/dart-lang/sdk/issues/47981

原来这里已经有票了:

https://github.com/dart-lang/sdk/issues/36983

我相信这里发生的事情是因为 _processWorkItemsInBackground 不是顶级函数,它正在关闭范围内的所有变量,这将包括此声明 late final ReceivePort _receivePort;。因此,当您使用 _processWorkItemsInBackground 生成隔离时,它会隐式地尝试将范围内的所有内容发送到隔离,但是不允许将 ReceivePort 发送到隔离,从而导致错误。