Loading...
Loading...
Offload heavy computation to isolates to keep the main thread responsive.
npx skill4agent add dart-lang/skills dart-concurrency-isolatesIsolate.run()Isolate.spawn()ReceivePortSendPortIsolate.runIsolate.run()import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
Future<Map<String, dynamic>> parseLargeJson(String filePath) async {
// Isolate.run spawns the isolate, runs the closure, returns the result, and exits.
return await Isolate.run(() async {
final fileData = await File(filePath).readAsString();
return jsonDecode(fileData) as Map<String, dynamic>;
});
}Isolate.spawnRemoteErrorRawReceivePortimport 'dart:async';
import 'dart:convert';
import 'dart:isolate';
class BackgroundWorker {
final SendPort _commands;
final ReceivePort _responses;
final Map<int, Completer<Object?>> _activeRequests = {};
int _idCounter = 0;
bool _closed = false;
BackgroundWorker._(this._responses, this._commands) {
_responses.listen(_handleResponsesFromIsolate);
}
static Future<BackgroundWorker> spawn() async {
final initPort = RawReceivePort();
final connection = Completer<(ReceivePort, SendPort)>.sync();
initPort.handler = (initialMessage) {
final commandPort = initialMessage as SendPort;
connection.complete((
ReceivePort.fromRawReceivePort(initPort),
commandPort,
));
};
try {
await Isolate.spawn(_startRemoteIsolate, initPort.sendPort);
} catch (e) {
initPort.close();
rethrow;
}
final (ReceivePort receivePort, SendPort sendPort) = await connection.future;
return BackgroundWorker._(receivePort, sendPort);
} static void _startRemoteIsolate(SendPort sendPort) {
final receivePort = ReceivePort();
sendPort.send(receivePort.sendPort);
receivePort.listen((message) {
if (message == 'shutdown') {
receivePort.close();
return;
}
final (int id, String payload) = message as (int, String);
try {
// Perform heavy computation here
final result = jsonDecode(payload);
sendPort.send((id, result));
} catch (e) {
sendPort.send((id, RemoteError(e.toString(), '')));
}
});
}Completer Future<Object?> executeTask(String payload) async {
if (_closed) throw StateError('Worker is closed');
final completer = Completer<Object?>.sync();
final id = _idCounter++;
_activeRequests[id] = completer;
_commands.send((id, payload));
return await completer.future;
}
void _handleResponsesFromIsolate(dynamic message) {
final (int id, Object? response) = message as (int, Object?);
final completer = _activeRequests.remove(id);
if (completer == null) return;
if (response is RemoteError) {
completer.completeError(response);
} else {
completer.complete(response);
}
if (_closed && _activeRequests.isEmpty) {
_responses.close();
}
} void close() {
if (!_closed) {
_closed = true;
_commands.send('shutdown');
if (_activeRequests.isEmpty) {
_responses.close();
}
}
}
}ReceivePort.close()SendPort.send()SocketPointerReceivePortIsolate.run()SendPortReceivePortdart-async-programming