Kako kreirati dva niti u Dart-u u kontekstu Flutter-a?
sobes.tech АИ
Одговор од АИ
U Dart/Flutter-u, izolati (Isolates) se koriste za kreiranje nezavisnih tokova izvršavanja. Oni predstavljaju odvojene zadatke sa sopstvenim memorijskim prostorom, što sprečava probleme sa konkurentnim pristupom podacima i blokiranje glavnog toka (UI toka).
Postoji nekoliko načina za kreiranje i interakciju sa izolatom:
-
Isolate.spawn(): Najniži nivo za kreiranje izolata. Zahteva prosleđivanje funkcije višeg nivoa ili statičke metode klase za izvršenje u novom izolatu i porta za razmenu poruka.import 'dart:isolate'; // Funkcija koja se izvršava u izolatu void isolateEntry(SendPort sendPort) { // Izvršavamo neku dugu operaciju int result = 0; for (int i = 0; i < 1000000000; i++) { result += i; } // Šaljemo rezultat nazad glavnom izolatu sendPort.send(result); } void main() async { ReceivePort receivePort = ReceivePort(); // Kreiramo novi izolat Isolate isolate = await Isolate.spawn(isolateEntry, receivePort.sendPort); // Slušamo poruke od izolata receivePort.listen((message) { print('Rezultat iz izolata: $message'); // Zaustavljamo izolata nakon primanja poruke isolate.kill(); }); print('Glavni tok nastavlja rad...'); } -
compute(): Pojednostavljena funkcija iz paketaflutter/foundation, koja koristiIsolate.spawn()u pozadini. Idealan je za jednostavne pozadinske zadatke koji ne zahtevaju složenu interakciju sa izolatom.import 'package:flutter/foundation.dart'; // Funkcija koja se izvršava pomoću compute int heavyComputation(int limit) { int result = 0; for (int i = 0; i < limit; i++) { result += i; } return result; } void main() async { print('Počinju teški računi u pozadini...'); // Izvršavamo funkciju u posebnom izolatu int result = await compute(heavyComputation, 1000000000); print('Rezultat računanja: $result'); print('Glavni tok nastavlja rad nakon računanja.'); } -
Isolate.spawnUri(): Koristi se za pokretanje koda iz posebnog fajladartu novom izolatu.
Interakcija između izolata:
Izolati razmenjuju podatke samo putem poruka preko instanci SendPort i ReceivePort. To su atomarne operacije koje ne zahtevaju blokade ili druge mehanizme za sinhronizaciju.
SendPort: Koristi se za slanje poruka iz jednog izolata u drugi.ReceivePort: Koristi se za slušanje dolaznih poruka.
Prilikom prenosa objekata između izolata, oni moraju biti "prenosiivi" (transferable), što uključuje:
- Jednostavne tipove podataka (int, double, String, bool)
- Liste i mape koje sadrže prenosiive tipove
- Neke specifične Flutter tipove koje je moguće serializovati
Objekti koji nisu prenosiivi biće kopirani, a njihove kasnije izmene u jednom izolatu neće se odraziti u drugom.
Ključne tačke:
- Izolati ne mogu direktno pristupati memoriji drugih.
- Nemaju pristup zajedničkom stanju, uključujući promenljive, klase i widget-e glavnog izolata (UI toka).
- Komunikacija između izolata odvija se asinhrono.
- U Flutter-u je važno pravilno upravljati njihovim životnim ciklusom (npr. korišćenjem
isolate.kill()ako je potrebno).
Korišćenje izolata omogućava izvršavanje dugotrajnih ili resursno zahtevnih operacija u pozadini, sprečavajući zamrzavanje korisničkog interfejsa i obezbeđujući glatko funkcionisanje aplikacije.