¿Cómo crear dos hilos en Dart en el contexto de Flutter?
sobes.tech AI
Respuesta de la IA
Para crear hilos de ejecución independientes en Dart/Flutter, se utilizan Aislas (Isolates). Son tareas separadas con su propio espacio de memoria dedicado, lo que previene problemas de acceso concurrente a los datos y bloqueos en el hilo principal (hilo UI).
Existen varias formas de crear e interactuar con los aislas:
-
Isolate.spawn(): La forma de bajo nivel para crear un aislamiento. Requiere pasar una función de nivel superior o un método estático de clase para ejecutar en el nuevo aislamiento y un puerto para intercambiar mensajes.import 'dart:isolate'; // Función que se ejecuta en el aislamiento void isolateEntry(SendPort sendPort) { // Realiza alguna operación larga int result = 0; for (int i = 0; i < 1000000000; i++) { result += i; } // Envía el resultado de vuelta al aislamiento principal sendPort.send(result); } void main() async { ReceivePort receivePort = ReceivePort(); // Crea un nuevo aislamiento Isolate isolate = await Isolate.spawn(isolateEntry, receivePort.sendPort); // Escucha los mensajes del aislamiento receivePort.listen((message) { print('Resultado del aislamiento: $message'); // Finaliza el aislamiento después de recibir el mensaje isolate.kill(); }); print('El hilo principal continúa trabajando...'); } -
compute(): Función simplificada del paqueteflutter/foundation, que usaIsolate.spawn()internamente. Es ideal para tareas de fondo simples que no requieren interacción compleja con el aislamiento.import 'package:flutter/foundation.dart'; // Función que se ejecuta con compute int heavyComputation(int limit) { int result = 0; for (int i = 0; i < limit; i++) { result += i; } return result; } void main() async { print('Comenzando cálculos pesados en segundo plano...'); // Ejecuta la función en un aislamiento separado int result = await compute(heavyComputation, 1000000000); print('Resultado de los cálculos: $result'); print('El hilo principal continúa después de los cálculos.'); } -
Isolate.spawnUri(): Se usa para ejecutar código desde un archivodartseparado en un nuevo aislamiento.
Interacción entre aislas:
Los aislas intercambian datos solo mediante envío de mensajes a través de instancias de SendPort y ReceivePort. Estas operaciones son atómicas, sin necesidad de bloqueos u otros mecanismos de sincronización.
SendPort: Se usa para enviar mensajes de un aislamiento a otro.ReceivePort: Se usa para escuchar mensajes entrantes.
Al transferir objetos entre aislas, estos deben ser "transferibles", lo que incluye:
- Tipos de datos simples (int, double, String, bool)
- Listas y mapas que contienen tipos transferibles
- Algunos tipos específicos de Flutter que pueden ser serializados
Los objetos que no son transferibles serán copiados, y sus cambios posteriores en un aislamiento no se reflejarán en el otro.
Puntos clave:
- Los aislas no pueden acceder directamente a la memoria del otro.
- Los aislas no tienen acceso a estado compartido, incluyendo variables, clases y widgets del aislamiento principal (hilo UI).
- La comunicación entre aislas es asíncrona.
- Al trabajar con aislas en Flutter, es importante gestionar correctamente su ciclo de vida (por ejemplo, usar
isolate.kill()si es necesario).
El uso de aislas permite realizar operaciones prolongadas o intensivas en recursos en segundo plano, evitando que la interfaz de usuario se congele y asegurando un funcionamiento fluido de la aplicación.