SoFunction
Updated on 2025-04-12

A detailed explanation of how Dart implements multitasking parallelism

Isolate (isolated area)

Dart is a programming language that supports multitasking parallelism, which provides multiple mechanisms to achieve concurrency and parallelism. Here are several ways Dart can implement multitasking parallelism:

Isolate in Dart is a lightweight concurrency mechanism similar to threading. Each isolation area is an independent memory space, each isolation area has its own memory space and execution thread, so code can be executed independently between different isolation areas, and each isolation area runs on its own core and does not block other Isolates. Concurrency is achieved. However, one thing needs to be noted that data cannot be shared directly between them and must be implemented through message delivery.

Here is a simple example code that shows how to implement concurrent execution in Dart using Isolate:

import 'dart:isolate';
void main() async {
  // Create two isolated areas  final isolate1 = await (runIsolate, 1);
  final isolate2 = await (runIsolate, 2);
  // Wait for the quarantine area to be completed  await ([, ]);
}
void runIsolate(int id) {
  // Code executed in the isolation area  print('Isolate $id is running');
}

In the example above, we first create two isolated regions using the function, each of which executes the runIsolate function and passes in different parameters (1 and 2). The runIsolate function is the code actually executed in the isolation area, it simply prints a piece of information.

After creating the quarantine area, we use the function to wait for the quarantine area to be executed. The exitCode property here returns the exit code of the isolated area, and if the code is successfully executed, it will return 0.

When we run the above code, we will see the following output:

Isolate 1 is running
Isolate 2 is running

It can be seen that the two isolation areas are started and executed almost simultaneously, achieving the effect of concurrent execution. This is just a simple example of Isolate, which you can use to perform more complex concurrent tasks, such as downloading multiple files simultaneously with multiple Isolate, or performing compute-intensive tasks in different isolation areas for improved performance, etc.

async/await

In Dart, async/await uses Future objects to implement asynchronous operations. When we preface async keywords to a function or method, this function becomes an asynchronous function. Using the await keyword in an asynchronous function can wait for the results of other asynchronous operations without blocking the execution of the current function.

Here is a demo code that uses async/await to implement asynchronous concurrency. It will download the content of two URLs at the same time and print the results after both download operations are completed:

import 'dart:async';
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
  final url1 = '';
  final url2 = '';
  final result1 = downloadUrl(url1);
  final result2 = downloadUrl(url2);
  final results = await ([result1, result2]);
  for (final result in results) {
    print(result);
  }
}
Future<String> downloadUrl(String url) async {
  final httpClient = HttpClient();
  final request = await ((url));
  final response = await ();
  final contents = await ().join();
  ();
  return contents;
}

In the above code, the downloadUrl method is an asynchronous function that uses the HttpClient class to download the contents of the given URL. In the main function, we use methods to wait for both download operations to complete and then print the result. Since result1 and result2 are performed simultaneously, the whole process is concurrent.

Stream

Stream in Dart is an event-based asynchronous programming model that can handle continuous asynchronous event streams. Use Stream to break down a long-running task into multiple small tasks, and the results can be pushed into the event stream after each small task is completed, so that other tasks can get the results asynchronously.

Here is a demo code that implements asynchronous concurrency using Stream. It will download data from two URLs and print the results:

import 'dart:async';
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
  final url1 = '';
  final url2 = '';
  final stream1 = downloadUrl(url1);
  final stream2 = downloadUrl(url2);
  await for (final result in ([stream1, stream2])) {
    print(result);
  }
}
Stream<String> downloadUrl(String url) async* {
  final httpClient = HttpClient();
  final request = await ((url));
  final response = await ();
  await for (final chunk in ()) {
    yield chunk;
  }
  ();
}

In the above code, the downloadUrl method returns a Stream object that is used to asynchronously download the contents of the given URL. In the main function, we use methods to merge the two download streams into one, and use await for loop to process the download results one by one.

It should be noted that in the downloadUrl method, we use the yield keyword to send the downloaded data blocks to the Stream one by one, so that the data can be sent continuously during the download process, without waiting for all the data to be downloaded and sent again. This is also one of the advantages of Stream when handling a large number of asynchronous events.

Compute Function

Compute Function in Dart is a function that can be run in a standalone Isolate that can take input parameters and return results. Use Compute Function to break down a compute-intensive task into multiple small tasks, use Compute Function to compute the results in parallel in each small task, and finally merge the results.

Here is a demo code that implements asynchronous concurrency using Compute Function. It will calculate two Fibonacci sequences and print the result:

import 'dart:async';
import 'package:flutter/';
Future<void> main() async {
  final result1 = compute(fibonacci, 40);
  final result2 = compute(fibonacci, 41);
  final results = await ([result1, result2]);
  for (final result in results) {
    print(result);
  }
}
int fibonacci(int n) {
  if (n == 0) return 0;
  if (n == 1) return 1;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

In the above code, we use the compute function to hand over the calculation task of the Fibonacci sequence to the background isolation thread for execution, and then use the method to wait for both tasks to complete and print the result.

It should be noted that when using compute function, the function passed to it must be a top-level function or a static function, because the background isolation thread cannot access non-static or instance variables.

Overall, Dart provides multiple mechanisms to implement multitasking parallelism, including Isolate, async/await, Stream, and Compute Function. These mechanisms can be selected and used according to specific task requirements, thereby achieving efficient concurrency and parallelism.

The above is a detailed explanation of how Dart realizes multitasking parallelism. For more information about Dart, please pay attention to my other related articles!