Table of contents
No headings in the article.
Dart is a client-optimized programming language used for building web, server, desktop, and mobile applications. One of its key features is isolates, which allow you to run a separate instance of your Dart code in a different thread with its own memory heap.
Why Use Isolates in Dart?
The primary advantage of using isolates in Dart is that they allow you to run code concurrently, meaning that you can perform multiple tasks simultaneously. This can greatly improve the performance of your application, especially if you are performing resource-intensive tasks.
Another advantage of isolates is that they allow you to run code in a completely separate thread, meaning that any issues or errors that occur within an isolate will not affect the rest of your application. This makes isolates an ideal solution for running code that is prone to errors or that requires a high level of stability.
How to Use Dart Isolates
To use isolates in Dart, you first need to create an isolate. To do this, you need to use the Isolate
class, which provides a method for launching an isolate.
Here's an example of how you might use isolates to perform a resource-intensive task:
import 'dart:isolate';
void main() {
// Create a new isolate and run the task
Isolate.spawn(task, null);
}
void task(SendPort sendPort) {
// Perform a resource-intensive task here
for (int i = 0; i < 100000000; i++) {
// ...
}
}
In this example, the Isolate.spawn
method is used to launch a new isolate and run the task
function. The task
function is run in a separate thread, meaning that it can perform a resource-intensive task without affecting the rest of the application.
Communication between Isolates
While isolates provide a way to run code in separate threads, it's also important to be able to communicate between isolates. Dart provides a SendPort
and ReceivePort
pair for communication between isolates.
Here's an example of how you might use SendPort
and ReceivePort
to communicate between isolates:
import 'dart:isolate';
void main() {
// Create a receive port to receive messages from the isolate
var receivePort = ReceivePort();
// Create a new isolate and run the task
Isolate.spawn(task, receivePort.sendPort);
// Listen for messages from the isolate
receivePort.listen((message) {
print('Received message: $message');
});
}
void task(SendPort sendPort) {
// Send a message to the main isolate
sendPort.send('Hello from the isolate!');
}
In this example, the ReceivePort
is used to receive messages from the isolate, while the SendPort
is used to send messages to the main isolate. The listen
method is used to listen for messages from the isolate, which can then be processed and used as needed.
De-serializing json using isolates
import 'dart:convert';
import 'dart:isolate';
Future<dynamic> parseJson(String jsonString) async {
// Create a receive port to receive messages from the isolate
var receivePort = ReceivePort();
// Define a future to wait for the result from the isolate
var result = receivePort.first.then((parsedJson) {
receivePort.close();
return parsedJson;
});
// Create a new isolate and run the task
Isolate.spawn(jsonParseTask, receivePort.sendPort);
// Return the future
return result;
}
void jsonParseTask(SendPort sendPort) {
// Parse the JSON string
var parsedJson = json.decode(jsonString);
// Send the parsed JSON to the main isolate
sendPort.send(parsedJson);
}
This code defines a new function called
parseJson
that takes ajsonString
as an argument and returns aFuture
that resolves to the parsed JSON. The function creates a new isolate and runs thejsonParseTask
function within it. ThejsonParseTask
function parses the JSON string and sends the result back to the main isolate, which can access it via theFuture
returned byparseJson
.
This function can be used as follows:
var jsonString = '{"name": "John Doe", "age": 35, "email": "john.doe@example.com"}';
parseJson(jsonString).then((parsedJson) {
print('Parsed JSON: $parsedJson');
});
Conclusion
Dart isolates provide a powerful way to run code concurrently and improve the performance of your application. By using the Isolate
class, SendPort
, and ReceivePort
, you can easily create and communicate between isolates, allowing you to perform complex and resource-intensive tasks.
The above example shows a basic use case. In Part 2, we will explore isolates in deep along with the latest isolate API changes in flutter 3.7