Dart Isolates
With the help of Dart, we can write asynchronous programs that don’t get blocked. The goal of asynchronous programming is concurrency. The thread has a variant called dart isolate. However, there is a significant distinction in how “Thread” and “Isolates” are often implemented. When compared to Thread, the isolation operates differently. The isolates are autonomous workers who communicate by sending messages across channels rather than sharing memories. Isolates requires a mechanism to serialize messages since it accomplishes its goal by passing messages.
Message forwarding is used to facilitate communication between the isolates as a client and server. It facilitates the program’s initialization of multicore microprocessor utilization.
To apply the isolate in our software, use the dart:isolate package, which comes with Dart. It offers a way to take single-threaded Dart code and turn it into something that lets the application utilize the hardware to its fullest.
Create and Start an Isolate
To construct an isolation, use the spawn() method offered by Dart. It needs to be declared with just one argument and a “entry point.” This field shows the port that is isolated and used to send back notifications.
Example
import 'dart:isolate';
void sayhii(var msg){
print('execution from sayhii ... the message is :${msg}');
}
void main(){
Isolate.spawn(sayhii,'Hello!!');
Isolate.spawn(sayhii,'Whats up!!');
Isolate.spawn(sayhii,'Welcome!!');
print('execution from main1');
print('execution from main2');
print('execution from main3');
}
Output
execution from main1
execution from main2
execution from main3
execution from sayhii ... the message is :Whats up!!
execution from sayhii ... the message is :Hello!!
Output 2
execution from main1
execution from main2
execution from main3
execution from sayhii ... the message is :Hello!!
execution from sayhii ... the message is :Welcome!!
Explanation
The spawn method of the isolate class in the program above carried out a function called sayhii in parallel with the remaining code. Two parameters are required.
- The string that will be supplied to the spawned function and the function that we wish to spawn.
The two functions we have, sayhii() and main(), might not always execute in the same order. The second output illustrates how the output will vary each time the aforementioned software is executed.
Note: If the spawning function has no objects to pass, we can alternatively pass NULL.
Example
void start() async {
ReceivePort receiverPort = ReceiverPort(); // Port for isolate to receive message.
isolate = await Isolate.spawn(runTimer, receiverPort.sendPort);
receivePort.listen((data){
stdout.write('Receiving: '+ data + ', ');
});
}
void runTimer(SendPort, sendPort) {
int coun = 0;
Timer.periodic(new Duration(seconds: 1), (Timer t) {
count++;
String msg = 'notification ' + count.toString();
stdout.write('Sending: ' + msg + ' -');
sendPort.send(msg);
});
}
Explanation
The code above provides an asynchronous method called start() that spawns an isolation and opens a port. We designated the start method as async so that it could store a reference to the new isolate and wait for the response from the isolates when they spawned. When we wish to eliminate the running isolated, it is important. The two parameters we gave to the spawn() method were the first, runTimer, which is a callback function used to execute runTimer(), and the second, sendPort, which is also a callback function used to send a message back to the caller. The receiverPort is first listening for messages from isolation using the start() method. It will print to the console as soon as it receives the message.
The runTimer() function starts a timer that updates a counter by firing once every second. It uses the port that it was given when the isolate was spawned to send a notification message.
Stop an Isolate
The kill() function, which is used to end an isolated process, is provided by the dart: isolates package.
Example
void stop() {
If (isolate != null) {
stdout.writeln('Stopping Isolate');
isolate.kill(priority: Isolate.immediate);
isolate = null;
}
}
Explanation
We have declared a stop() function in the example above, which will end the running isolation and set its reference to null. We established an immediate priority for isolation, meaning that it will end as quickly as possible.
Complete Program
Example
import 'dart:io';
import 'dart:async';
import 'dart:isolate';
Isolate isolate;
// Start the isolate
void start() async {
ReceivePort receiverPort = ReceiverPort(); // Port for isolate to receive message.
isolate = await Isolate.spawn(runTimer, receiverPort.sendPort);
receivePort.listen((data){
stdout.write('Receiving: '+ data + ', ');
});
}
void runTimer(SendPort, sendPort) {
int coun = 0;
Timer.periodic(new Duration(seconds: 1), (Timer t) {
count++;
String msg = 'notification ' + count.toString();
stdout.write('Sending: ' + msg + ' -');
sendPort.send(msg);
});
}
// Stopping the isolate using the stop() function.
void stop() {
if (isolate != null) {
stdout.writeln('Stopping Isolate.....');
isolate.kill(priority:Isolate.immediate);
isolate = null;
}
}
void main() async {
stdout.writeln('Starting Isolate...');
await start();
std.writeln('Hit enter key to quit');
await stdin.first;
stop();
stdout.writeln('Bye!');
exit(0);
}
Output
Stating Isolate
Hit enter key to quit
Sending: notification 1 - Receiving: notification 1, Sending: notification 2 - Receiving: notification 2,
Stopping Isolate