ReceivePort în Dart

Cutia poștală a unui izolat: un Stream cu mesajele primite; sendPort este adresa ei, close o închide.

Sintaxă
import 'dart:isolate';

abstract interface class ReceivePort implements Stream<dynamic>
ReceivePort([String debugName = ''])
SendPort get sendPort
void close()

Ce face ReceivePort

Un ReceivePort primește mesajele trimise prin sendPort-ul lui, din orice izolat. Este un Stream<dynamic> obișnuit, deci îl citești cu await for, listen, first sau take.

sendPort este adresa pe care o dai altor izolate ca să-ți scrie. close() închide portul: stream-ul se termină și nu mai primești mesaje. Un port deschis ține programul în viață, așa că închide-l când nu mai ai nevoie de el.

Ce returnează

sendPort returnează un SendPort; close nu returnează nimic.

Exemple

Exemplul 1: Mesaje trimise chiar din izolatul principal

import 'dart:isolate';

Future<void> main() async {
  final cutie = ReceivePort();
  cutie.sendPort.send('Bună, Ana!');
  cutie.sendPort.send(42);
  cutie.sendPort.send(['Iași', 'Cluj']);

  final primite = await cutie.take(3).toList();
  for (final m in primite) {
    print('${m.runtimeType}: $m');
  }
}

Rezultat

String: Bună, Ana!
int: 42
List<String>: [Iași, Cluj]

Exemplul 2: close termină stream-ul portului

import 'dart:isolate';

void numara(SendPort port) {
  for (var i = 1; i <= 3; i++) {
    port.send(i);
  }
  port.send('gata');
}

Future<void> main() async {
  final port = ReceivePort();
  await Isolate.spawn(numara, port.sendPort);
  await for (final m in port) {
    print('primit $m');
    if (m == 'gata') port.close();
  }
  print('portul este închis, bucla s-a terminat');
}

Rezultat

primit 1
primit 2
primit 3
primit gata
portul este închis, bucla s-a terminat

Greșeli frecvente

  • Asculți un ReceivePort de două ori. Este un stream obișnuit, cu un singur ascultător; dacă ai nevoie de mai mulți, folosește asBroadcastStream().
  • Nu închizi portul și programul nu se mai termină.

Comenzi înrudite

  • SendPort: Adresa unui ReceivePort; send trimite un mesaj (o copie a datelor) către izolatul care deține portul.
  • Isolate.spawn: Pornește un izolat de durată, care rulează o funcție cu un mesaj inițial; kill îl oprește.
  • Stream: Un șir de valori care sosesc în timp, una după alta (mesaje, clicuri, linii dintr-un fișier); îl parcurgi cu await for.
  • Stream.asBroadcastStream: Transformă un stream obișnuit într-unul broadcast, care poate avea mai mulți ascultători în același timp.