← Назад к вопросам
Что такое Isolate в Dart и когда его использовать?
2.0 Middle🔥 192 комментариев
#Dart#Асинхронность
Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Isolate в Dart
Isolate (Изолят) — это независимый поток выполнения в Dart с собственной памятью и Event Loop. Это единственный способ в Dart получить настоящую многопоточность, так как обычный код выполняется в одном потоке.
Почему нужны Isolates
Dart работает в одном потоке с Event Loop. Если выполнить тяжёлую операцию (криптография, парсинг JSON, обработка изображений), UI зависнет:
// Плохо: блокирует UI на 5 секунд
void main() async {
print('Start');
// Тяжёлое вычисление в главном потоке
final result = await heavyComputation(); // 5 сек
print('Done: $result');
}
Future<int> heavyComputation() async {
int sum = 0;
for (int i = 0; i < 1000000000; i++) {
sum += i;
}
return sum;
}
// Результат: UI зависает на 5 сек, кнопки не реагируют, анимация прерывается
Решение: Isolate
import 'dart:isolate';
void main() async {
print('Start');
// Создаём isolate для тяжёлого вычисления
final result = await Isolate.run(heavyComputation);
print('Done: $result'); // UI не зависла!
}
int heavyComputation() {
int sum = 0;
for (int i = 0; i < 1000000000; i++) {
sum += i;
}
return sum;
}
// Результат: UI остаётся отзывчивым, вычисление выполняется в отдельном потоке
Как работает Isolate
1. Создание простого Isolate (Dart 2.10+)
import 'dart:isolate';
void main() async {
// Самый простой способ
final result = await Isolate.run(heavyTask);
print('Result: $result');
}
int heavyTask() {
return 42 * 1000000000;
}
2. Традиционный способ (более гибкий)
import 'dart:isolate';
void isolateEntry(SendPort sendPort) {
// Это выполняется в отдельном isolate
final result = 42;
sendPort.send(result); // Отправляем результат в главный isolate
}
void main() async {
// Создаём ReceivePort для получения данных
final receivePort = ReceivePort();
// Создаём isolate
await Isolate.spawn(isolateEntry, receivePort.sendPort);
// Ждём результата
final result = await receivePort.first;
print('Result: $result');
}
Двусторонняя коммуникация
import 'dart:isolate';
void isolateEntry(SendPort mainSendPort) {
// Создаём ReceivePort для получения сообщений из главного isolate
final isolateReceivePort = ReceivePort();
// Отправляем наш SendPort в главный isolate
mainSendPort.send(isolateReceivePort.sendPort);
// Слушаем сообщения
isolateReceivePort.listen((message) {
print('Isolate received: $message');
// Обработка и отправка результата
final result = message * 2;
mainSendPort.send(result);
});
}
void main() async {
final receivePort = ReceivePort();
// Создаём isolate
await Isolate.spawn(isolateEntry, receivePort.sendPort);
// Получаем SendPort изолята
final isolateSendPort = await receivePort.first as SendPort;
// Отправляем сообщение
isolateSendPort.send(5);
// Получаем результат
final result = await receivePort.first;
print('Main received: $result'); // 10
}
Практические примеры
Пример 1: Обработка изображений
import 'dart:isolate';
import 'package:image/image.dart';
Image processImage(String imagePath) {
// Читаем и обрабатываем изображение в отдельном потоке
final image = decodeImage(File(imagePath).readAsBytesSync())!;
return brightness(image, 50);
}
void main() async {
// UI остаётся отзывчивым
final processedImage = await Isolate.run(
() => processImage('large_image.jpg'),
);
print('Image processed');
}
Пример 2: Парсинг больших JSON
import 'dart:isolate';
import 'dart:convert';
List<User> parseUsers(String jsonString) {
final jsonData = jsonDecode(jsonString) as List;
return jsonData
.map((json) => User.fromJson(json))
.toList();
}
void main() async {
final jsonString = await File('large_file.json').readAsString();
// Парсим в отдельном потоке
final users = await Isolate.run(
() => parseUsers(jsonString),
);
print('Parsed ${users.length} users');
}
Пример 3: Криптография
import 'dart:isolate';
import 'package:crypto/crypto.dart';
String hashPassword(String password) {
// Хеширование в отдельном потоке
return sha256.convert(utf8.encode(password)).toString();
}
void main() async {
final password = 'my_secure_password';
final hash = await Isolate.run(
() => hashPassword(password),
);
print('Hash: $hash');
}
Когда использовать Isolate
Используй Isolate для:
- Обработка больших объёмов данных (JSON, XML)
- Криптографические операции (хеширование, шифрование)
- Обработка изображений и видео
- Сложные математические вычисления
- Долгие операции ввода-вывода (файлы, БД)
- Machine Learning инференс
Не используй Isolate для:
- Простых асинхронных операций (HTTP, таймеры)
- Коротких операций (< 1мс)
- Работы с UI (не можешь обновить widget из isolate)
Ограничения Isolates
// Isolates не могут обновлять UI
void isolateEntry(SendPort sendPort) {
// Это НЕ РАБОТАЕТ:
// setState(() => counter++); // Error!
// Вместо этого отправляем данные в главный isolate
sendPort.send(counter);
}
// Isolates не могут использовать некоторые объекты
// (например, HttpClient, которые зависят от главного isolate)
Flutter с Isolates
import 'dart:isolate';
import 'package:flutter/material.dart';
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _result = 0;
bool _loading = false;
void _startComputation() async {
setState(() => _loading = true);
// Запускаем тяжёлое вычисление в isolate
_result = await Isolate.run(heavyComputation);
setState(() => _loading = false);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Isolate Example')),
body: Center(
child: _loading
? CircularProgressIndicator()
: Text('Result: $_result'),
),
floatingActionButton: FloatingActionButton(
onPressed: _startComputation,
child: Icon(Icons.play_arrow),
),
);
}
}
int heavyComputation() {
int sum = 0;
for (int i = 0; i < 1000000000; i++) {
sum += i;
}
return sum;
}
Производительность
- Создание Isolate — ~1-10мс (небольшие издержки)
- Передача данных — скопирование (не share), может быть дорого для больших объектов
- Использование SendPort — очень эффективно для обмена сообщениями
Isolate — это мощный инструмент для масштабирования приложений Flutter на многоядерные процессоры.