I was trying to write my own worker to process big amount of numbers. And decided to make always working Isolate in which all my data would be processed.
class ProjectionWorker {
...
Isolate? _isolate;
ReceivePort? _workerPort;
Stream? _workerResultStream;
SendPort? _isolatePort;
Future<ObjectModel> project(
ObjectModel model,
ProjectionData projectionData,
) async {
_workerPort ??= ReceivePort();
_isolate ??= await Isolate.spawn<SendPort>(
_isolateScope,
_workerPort!.sendPort,
debugName: "flutter_object calculations",
);
_workerResultStream ??= _workerPort!.asBroadcastStream();
_isolatePort ??= await _workerResultStream!.first;
final Completer<ObjectModel> completer = Completer();
_workerResultStream!.listen(
(result) {
if (result is ObjectModel) completer.complete(result);
},
);
_isolatePort!.send(
Tuple(
model,
projectionData,
),
);
return completer.future;
}
}
...
void _isolateScope(SendPort port) async {
final isolatePort = ReceivePort();
port.send(isolatePort.sendPort);
await for (final event in isolatePort) {
...
port.send(result);
}
}
But when I tried to use it in my custom RenderObject, in paint
method:
Future<void> _projectObject({
...
}) async {
_projectedObject = await _projectionWorker.project(
...
);
I am receiving this:
Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: (object is a ReceivePort)
And exception throws from this line of code:
... 👇
_isolatePort!.send(
Tuple(
model,
projectionData,
),
);
...
Am I missing something here?
I just figured it out.
It seems stupid, but it worked out for me, so I hope, it would help somebody else.
In my isolateScope
function ReceivePort
gets tuple with ObjectModel
and ProjectionData
ProjectionData
was containing Size
property in it, and ObjectModel
had Color
property.
I cut that both properties out and replaced it with just double
or List
.
And it just worked out.
It seems, that isolate somehow gets RecievePort
by importing flutter/material.dart
.