Sobes.tech
Middle

Kā izveidot divus pavedienus Dart valodā Flutter kontekstā?

sobes.tech AI

Atbilde no AI

Dart/Flutter izmanto izolātus (Isolates) neatkarīgu izpildes plūsmu izveidei. Tie ir atsevišķi uzdevumu vienības ar savu atmiņas telpu, kas novērš konkurējošas piekļuves problēmas pie datiem un galvenā plūsmas (UI plūsmas).

Ir vairāki veidi, kā izveidot un sadarboties ar izolātiem:

  1. Isolate.spawn(): zemākā līmeņa izolāta izveides veids. Prasa nodot augšējā līmeņa funkciju vai statisku klases metodi, kas tiks izpildīta jaunajā izolātā, un portu ziņojumu apmaiņai.

    import 'dart:isolate';
    
    // Funkcija, kas tiks izpildīta izolātā
    void isolateEntry(SendPort sendPort) {
      // Veikt ilgu operāciju
      int result = 0;
      for (int i = 0; i < 1000000000; i++) {
        result += i;
      }
      // Nosūtīt rezultātu atpakaļ galvenajam izolātam
      sendPort.send(result);
    }
    
    void main() async {
      ReceivePort receivePort = ReceivePort();
      // Izveidot jaunu izolātu
      Isolate isolate = await Isolate.spawn(isolateEntry, receivePort.sendPort);
    
      // Klausīties ziņojumus no izolāta
      receivePort.listen((message) {
        print('Rezultāts no izolāta: $message');
        // Pārtraukt izolātu pēc ziņojuma saņemšanas
        isolate.kill();
      });
    
      print('Galvenais plūsma turpina darbu...');
    }
    
  2. compute(): vienkārša funkcija no flutter/foundation pakotnes, kas izmanto Isolate.spawn() fonā. Ideāli piemērota vienkāršiem fonu uzdevumiem, kuri neprasa sarežģītu mijiedarbību ar izolātu.

    import 'package:flutter/foundation.dart';
    
    // Funkcija, kas tiks izpildīta ar compute
    int heavyComputation(int limit) {
      int result = 0;
      for (int i = 0; i < limit; i++) {
        result += i;
      }
      return result;
    }
    
    void main() async {
      print('Sākam smagas skaitļošanas fonā...');
      // Izpildīt funkciju atsevišķā izolātā
      int result = await compute(heavyComputation, 1000000000);
      print('Skaitļošanas rezultāts: $result');
      print('Galvenais plūsma turpina darbu pēc skaitļošanas.');
    }
    
  3. Isolate.spawnUri(): izmanto, lai palaistu kodu no atsevišķa dart faila jaunā izolātā.

Sadarbība starp izolātiem:

Izolāti apmainās ar datiem tikai, pārsūtot ziņojumus caur SendPort un ReceivePort instancēm. Šīs ir atomāras operācijas, kas neprasa bloķēšanu vai citus sinhronizācijas mehānismus.

  • SendPort: izmanto, lai sūtītu ziņojumus no viena izolāta uz citu.
  • ReceivePort: izmanto, lai klausītos ienākošos ziņojumus.

Pārsūtot objektus starp izolātiem, tie jābūt "pārsūtāmiem" (transferable), kas ietver:

  • Vienkāršus datu tipus (int, double, String, bool)
  • Sarakstus un kartes, kas satur pārsūtāmus tipus
  • Dažus Flutter specifiskus tipus, kuri var tikt serializēti

Objekti, kas nav pārsūtāmi, tiks kopēti, un to turpmākās izmaiņas vienā izolātā neietekmēs otru.

Galvenie punkti:

  • Izolāti nevar tieši piekļūt viens otra atmiņai.
  • Izolātiem nav piekļuves kopējai stāvokļa informācijai, tostarp mainīgajiem, klasēm un vidgetiem galvenajā izolātā (UI plūsmā).
  • Saziņa starp izolātiem notiek asinhroni.
  • Darbojoties ar izolātiem Flutter, ir svarīgi pareizi pārvaldīt to dzīves ciklu (piemēram, izmantot isolate.kill() ja nepieciešams).

Izolātu izmantošana ļauj veikt ilgstošas vai resursu prasīgas operācijas fonā, novēršot lietotāja saskarnes aizsaldēšanu un nodrošinot gludu lietotāja pieredzi.