SendPort în Dart

Adresa unui ReceivePort; send trimite un mesaj (o copie a datelor) către izolatul care deține portul.

Sintaxă
import 'dart:isolate';

abstract interface class SendPort implements Capability
void send(Object? message)

Ce face SendPort

sendPort.send(mesaj) trimite mesajul către ReceivePort-ul corespunzător. Mesajul este copiat: izolatul care primește are propria copie, deci modificările ei nu se văd în izolatul care a trimis.

Se pot trimite null, numere, texte, liste, map-uri, records, obiecte simple și chiar alte SendPort-uri. Prin trimiterea unui SendPort poți crea o comunicare în ambele sensuri: lucrătorul îți trimite portul lui, iar tu îi trimiți sarcini.

Parametri

Parametru Descriere
message Valoarea trimisă.

Ce returnează

Nimic (void); trimiterea este asincronă.

Exemple

Exemplul 1: Comunicare în ambele sensuri

import 'dart:isolate';

void calculator(SendPort catreMain) {
  final sarcini = ReceivePort();
  catreMain.send(sarcini.sendPort);
  sarcini.listen((mesaj) {
    if (mesaj == 'stop') {
      sarcini.close();
      return;
    }
    final (int a, int b) = mesaj as (int, int);
    catreMain.send('$a x $b = ${a * b}');
  });
}

Future<void> main() async {
  final dinLucrator = ReceivePort();
  await Isolate.spawn(calculator, dinLucrator.sendPort);
  final mesaje = dinLucrator.asBroadcastStream();

  final catreLucrator = await mesaje.first as SendPort;
  for (final p in [(6, 7), (12, 12)]) {
    catreLucrator.send(p);
    print(await mesaje.first);
  }
  catreLucrator.send('stop');
  dinLucrator.close();
}

Rezultat

6 x 7 = 42
12 x 12 = 144

Exemplul 2: Mesajul este o copie

import 'dart:isolate';

void modifica(List<Object> date) {
  final lista = date[0] as List<String>;
  final raspuns = date[1] as SendPort;
  lista.add('Brașov');
  raspuns.send(lista);
}

Future<void> main() async {
  final orase = ['Iași', 'Cluj'];
  final port = ReceivePort();
  await Isolate.spawn(modifica, [orase, port.sendPort]);
  print('în izolatul nou: ${await port.first}');
  print('în main: $orase');
}

Rezultat

în izolatul nou: [Iași, Cluj, Brașov]
în main: [Iași, Cluj]

Greșeli frecvente

  • Trimiți un obiect care ține resurse ale sistemului (un fișier deschis, un ReceivePort, un socket). Apare o eroare; trimite doar date.

Comenzi înrudite

  • ReceivePort: Cutia poștală a unui izolat: un Stream cu mesajele primite; sendPort este adresa ei, close o închide.
  • Isolate.spawn: Pornește un izolat de durată, care rulează o funcție cu un mesaj inițial; kill îl oprește.
  • Isolate: Un fir de execuție separat, cu memoria lui; Isolate.current este izolatul în care rulează codul acum.