Sobes.tech
Middle

Ինչպես ստեղծել երկու հոսք Dart-ում Flutter-ի կոնտեքստում?

sobes.tech AI

Պատասխան AI-ից

Dart/Flutter-ում անկախ կատարման հոսքերը (Isolates) օգտագործվում են: Նրանք ներկայացնում են առանձին առաջադրանքներ սեփական հիշողության տարածքով, ինչը կանխում է տվյալների մրցակցային մուտքը և հիմնական հոսքի (UI հոսք) բլոկավորումը:

Կան մի քանի եղանակներ՝ ինչպես ստեղծել և փոխազդել հետ՝ isolat-ների հետ:

  1. Isolate.spawn(): Ամենացածր մակարդակի եղանակը՝ isolat-ներ ստեղծելու համար: Պահանջում է վերևի մակարդակի ֆունկցիայի կամ դասի ստատիկ մեթոդի փոխանցում՝ նոր isolat-ում գործելու համար, և հաղորդագրությունների փոխանակման համար պորտ:

    import 'dart:isolate';
    
    // Ֆունկցիա, որը գործարկվում է isolat-ում
    void isolateEntry(SendPort sendPort) {
      // Մի երկարատև գործողություն կատարում ենք
      int result = 0;
      for (int i = 0; i < 1000000000; i++) {
        result += i;
      }
      // Արդյունքը ուղարկում ենք հիմնական isolat-ին
      sendPort.send(result);
    }
    
    void main() async {
      ReceivePort receivePort = ReceivePort();
      // Ստեղծում ենք նոր isolat
      Isolate isolate = await Isolate.spawn(isolateEntry, receivePort.sendPort);
    
      // Հետևում ենք isolat-ից ստացված հաղորդագրություններին
      receivePort.listen((message) {
        print('Ազատ isolat-ից արդյունքը: $message');
        // Բացում ենք isolat-ը հաղորդագրություն ստանալուց հետո
        isolate.kill();
      });
    
      print('Հիմնական հոսքը շարունակում է աշխատել...');
    }
    
  2. compute(): Պարզեցված ֆունկցիա՝ flutter/foundation փաթեթից, որը օգտագործում է Isolate.spawn()-ը ներքևից:

    import 'package:flutter/foundation.dart';
    
    // Ֆունկցիա, որը գործարկվում է compute-ի միջոցով
    int heavyComputation(int limit) {
      int result = 0;
      for (int i = 0; i < limit; i++) {
        result += i;
      }
      return result;
    }
    
    void main() async {
      print('Սկսում ենք ծանր հաշվարկներ ֆոնին...');
      // Կատարում ենք ֆունկցիան առանձին isolat-ում
      int result = await compute(heavyComputation, 1000000000);
      print('Հաշվարկների արդյունքը: $result');
      print('Հիմնական հոսքը շարունակում է աշխատանքը հաշվարկներից հետո...');
    }
    
  3. Isolate.spawnUri(): Օգտագործվում է կոդը գործարկելու համար առանձին dart ֆայլից՝ նոր isolat-ում:

Միջհամակարգային փոխազդեցություն isolat-ների միջև:

Իզոլատները փոխանակում են տվյալները միայն հաղորդագրությունների միջոցով՝ SendPort և ReceivePort օրինակների միջոցով: Այս գործողությունները ագրեգատային են և չեն պահանջում սեղմումներ կամ այլ սինխրոնիզացիայի մեխանիզմներ:

  • SendPort: օգտագործվում է հաղորդագրություններ ուղարկելու համար մեկ isolat-ից մյուսին:
  • ReceivePort: օգտագործվում է ստացվող հաղորդագրությունները լսելու համար:

Տվյալների փոխանցման ժամանակ, օբյեկտները պետք է լինեն "փոխանցելի" (transferable), ինչը ներառում է՝

  • պարզ տվյալների տիպեր (int, double, String, bool)
  • ցանկեր և քարտեզներ, որոնք պարունակում են փոխանցելի տիպեր
  • որոշ հատուկ Flutter տիպեր, որոնք կարող են(serialized) լինել

Փոխանցելի olmayan օբյեկտները կկոպիանվեն, և նրանց հետագա փոփոխությունները մեկ isolat-ում չեն արտացոլվի մյուսում:

Հիմնական կետեր:

  • isolat-ները չեն կարող ուղղակի մուտք գործել միմյանց հիշողություն:
  • նրանք չունեն ընդհանուր վիճակ, ներառյալ փոփոխականները, դասերը և հիմնական isolat-ի (UI) վիջեթները:
  • հաղորդակցությունը isolat-ների միջև կատարվում է ասինխրոն:
  • Flutter-ում կարևոր է ճիշտ կառավարել նրանց կյանքի ցիկլը (օրինակ, օգտագործելով isolate.kill() անհրաժեշտության դեպքում):

isolat-ների օգտագործումը թույլ է տալիս իրականացնել երկարաժամկետ կամ ռեսուրսային ծանր գործողություններ ֆոնային ռեժիմում, կանխելով օգտագործողի ինտերֆեյսի կախվելը և ապահովելով ծրագրի հարթ աշխատանքը։