无效参数:隔离消息中的非法参数:(对象是接收端口)
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
发送到隔离,从而导致错误。
我不确定我是否在这段代码中做错了什么,但我在生成新的 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
发送到隔离,从而导致错误。