start method
Starts execution of this Thread in a new Isolate.
The entry function passed to this thread must be a top-level or static
function. Once started, the Isolate will execute that function with
an internal ThreadMessage containing a SendPort
and optional data.
Throws InvalidArgumentException if called more than once.
Example:
await thread.start();
Implementation
Future<void> start() async {
if (_isolate != null) {
throw InvalidArgumentException('DartThread already started.');
}
_receivePort = ReceivePort();
_joinCompleter = Completer<void>();
_isolate = await Isolate.spawn<ThreadMessage>(
_entryPoint,
ThreadMessage(_receivePort!.sendPort, initialMessage),
debugName: _debugName,
errorsAreFatal: true,
);
_activeThreads[_isolate!] = this; // Register the thread instance
_receivePort!.listen((message) {
if (message == 'done') {
_joinCompleter?.complete();
_receivePort?.close();
_activeThreads.remove(_isolate); // Unregister on completion
_isolate = null;
} else if (message is List && message[0] == 'error') {
_joinCompleter?.completeError(ThreadSpawnException(message[1], cause: message[2]));
_receivePort?.close();
_activeThreads.remove(_isolate); // Unregister on error
_isolate = null;
}
}, onError: (error) {
_joinCompleter?.completeError(error);
_receivePort?.close();
_activeThreads.remove(_isolate); // Unregister on error
_isolate = null;
}, onDone: () {
// This callback is invoked when the ReceivePort is closed.
// If the completer is not yet completed, it means:
// 1. The Isolate exited without sending 'done' or an explicit error message.
// 2. The Isolate was killed by `interrupt()`.
// In both cases, it's not a successful completion from the perspective of `join()`.
if (!(_joinCompleter?.isCompleted ?? false)) {
// If it was killed by interrupt(), interrupt() already called completeError.
// If it exited unexpectedly, we should complete with an error.
_joinCompleter?.completeError(ThreadInterruptedException('Isolate $_debugName terminated unexpectedly or was interrupted.'));
}
_activeThreads.remove(_isolate); // Ensure unregistration on any done event
});
}