Volver a la página principal
jueves 31 octubre 2024
8

Cómo usar Isolates en Dart

En Dart, los Isolates son hilos de ejecución independientes que permiten ejecutar código en paralelo, de manera que pueden realizar tareas intensivas sin bloquear el hilo principal de la aplicación. A diferencia de otros modelos de hilos, los Isolates en Dart no comparten memoria, lo que los hace seguros para manejar tareas en paralelo, especialmente en Flutter y en aplicaciones de servidor de Dart.

¿Qué son los Isolates en Dart?

Un Isolate es una unidad de ejecución independiente que tiene su propio espacio de memoria y no comparte estado con otros Isolates. La comunicación entre Isolates se realiza a través de mensajes, utilizando SendPort y ReceivePort. Los Isolates son útiles para realizar operaciones intensivas en CPU, como cálculos complejos, manipulación de archivos y decodificación de imágenes, sin afectar el rendimiento de la interfaz de usuario.

Sintaxis básica de Isolates

Para crear y usar un Isolate, primero necesitas una función que realice la tarea. Luego, puedes utilizar el método Isolate.spawn para lanzar el Isolate y comunicarte a través de mensajes.

import 'dart:isolate';

void tarea(Int param) {
  print("Ejecutando tarea con parámetro: $param");
}

void main() {
  Isolate.spawn(tarea, 10);
  print("Isolate creado");
}

Este código crea un Isolate que ejecuta la función tarea con el parámetro 10.

Ejemplos de uso de Isolates en Dart

Comunicación entre Isolates

Para recibir y enviar datos entre Isolates, puedes usar SendPort y ReceivePort. ReceivePort recibe los datos, y SendPort permite enviarlos.

import 'dart:isolate';

void tarea(SendPort sendPort) {
  sendPort.send("Mensaje desde el Isolate");
}

void main() async {
  ReceivePort receivePort = ReceivePort();

  await Isolate.spawn(tarea, receivePort.sendPort);

  receivePort.listen((mensaje) {
    print("Mensaje recibido: $mensaje");
    receivePort.close(); // Cerrar el puerto después de recibir el mensaje
  });
}

En este ejemplo, el Isolate envía un mensaje al ReceivePort, que lo imprime y luego cierra la comunicación.

Enviar y recibir datos complejos

Puedes enviar y recibir datos complejos (como listas y mapas) a través de SendPort y ReceivePort.

import 'dart:isolate';

void calcularSuma(List<dynamic> args) {
  int suma = args[0] + args[1];
  SendPort sendPort = args[2];
  sendPort.send(suma);
}

void main() async {
  ReceivePort receivePort = ReceivePort();
  
  await Isolate.spawn(calcularSuma, [3, 5, receivePort.sendPort]);

  receivePort.listen((resultado) {
    print("La suma es: $resultado"); // Imprime: La suma es: 8
    receivePort.close();
  });
}

En este ejemplo, se envían dos números al Isolate junto con un SendPort. El Isolate calcula la suma y envía el resultado de vuelta.

Usar Isolates para tareas intensivas

Los Isolates son especialmente útiles en Flutter para ejecutar tareas que consumen muchos recursos sin afectar la fluidez de la interfaz de usuario.

import 'dart:isolate';

void tareaPesada(SendPort sendPort) {
  int resultado = 0;
  for (int i = 0; i < 100000000; i++) {
    resultado += i;
  }
  sendPort.send(resultado);
}

void main() async {
  ReceivePort receivePort = ReceivePort();

  await Isolate.spawn(tareaPesada, receivePort.sendPort);

  receivePort.listen((resultado) {
    print("Resultado de la tarea intensiva: $resultado");
    receivePort.close();
  });
}

Este código ejecuta una tarea intensiva en un Isolate para evitar que el programa principal se bloquee.

Cerrar un Isolate

Cerrar un Isolate cuando ya no es necesario es importante para liberar recursos. Puedes usar el método kill para finalizarlo.

import 'dart:isolate';

void tarea(SendPort sendPort) {
  sendPort.send("Tarea completada");
}

void main() async {
  ReceivePort receivePort = ReceivePort();
  Isolate isolate = await Isolate.spawn(tarea, receivePort.sendPort);

  receivePort.listen((mensaje) {
    print(mensaje);
    receivePort.close();
    isolate.kill(priority: Isolate.immediate); // Finalizar el Isolate
  });
}

Ventajas de los Isolates

  • Paralelismo: Permiten ejecutar código en paralelo, mejorando el rendimiento en tareas complejas.
  • Seguridad: La falta de memoria compartida evita problemas de concurrencia.
  • Eficiencia en Flutter: Son esenciales para evitar bloqueos en la interfaz de usuario cuando se ejecutan tareas pesadas.

Referencia oficial

Para obtener más información sobre Isolates, consulta la documentación oficial de Dart sobre Isolates.

Etiquetas:
Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer