Πώς δημιουργείτε δύο νήματα σε Dart στο πλαίσιο του Flutter;
sobes.tech AI
Απάντηση από AI
Στη Dart/Flutter, χρησιμοποιούνται Απομονώσεις (Isolates) για τη δημιουργία ανεξάρτητων ροών εκτέλεσης. Αυτές αποτελούν ξεχωριστές εργασίες με δικό τους χώρο μνήμης, αποτρέποντας προβλήματα ανταγωνιστικής πρόσβασης σε δεδομένα και μπλοκάρισμα της κύριας ροής (UI).
Υπάρχουν διάφοροι τρόποι δημιουργίας και αλληλεπίδρασης με τις απομονώσεις:
-
Isolate.spawn(): Ο χαμηλότερου επιπέδου τρόπος δημιουργίας απομόνωσης. Απαιτεί την παροχή μιας ανώτερης λειτουργίας ή στατικής μεθόδου και μιας θύρας για ανταλλαγή μηνυμάτων.import 'dart:isolate'; // Συνάρτηση που εκτελείται στην απομόνωση void isolateEntry(SendPort sendPort) { // Εκτελούμε μια μακράς διάρκειας λειτουργία int result = 0; for (int i = 0; i < 1000000000; i++) { result += i; } // Αποστέλλουμε το αποτέλεσμα πίσω στην κύρια απομόνωση sendPort.send(result); } void main() async { ReceivePort receivePort = ReceivePort(); // Δημιουργούμε μια νέα απομόνωση Isolate isolate = await Isolate.spawn(isolateEntry, receivePort.sendPort); // Ακούμε μηνύματα από την απομόνωση receivePort.listen((message) { print('Αποτέλεσμα από την απομόνωση: $message'); // Τερματίζουμε την απομόνωση μετά τη λήψη του μηνύματος isolate.kill(); }); print('Ο κύριος ροή συνεχίζει την εργασία...'); } -
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('Ξεκινάμε βαριές υπολογιστικές εργασίες στο φόντο...'); // Εκτελούμε τη λειτουργία σε ξεχωριστή απομόνωση int result = await compute(heavyComputation, 1000000000); print('Αποτέλεσμα υπολογισμών: $result'); print('Ο κύριος ροή συνεχίζει μετά τους υπολογισμούς.'); } -
Isolate.spawnUri(): Χρησιμοποιείται για την εκτέλεση κώδικα από ένα ξεχωριστό αρχείοdartσε μια νέα απομόνωση.
Αλληλεπίδραση μεταξύ απομονώσεων:
Οι απομονώσεις ανταλλάσσουν δεδομένα μόνο μέσω αποστολής μηνυμάτων μέσω των αντικειμένων SendPort και ReceivePort. Αυτές οι λειτουργίες είναι ατομικές και δεν απαιτούν κλειδώματα ή άλλα μηχανισμούς συγχρονισμού.
SendPort: Χρησιμοποιείται για την αποστολή μηνυμάτων από μια απομόνωση σε άλλη.ReceivePort: Χρησιμοποιείται για την παρακολούθηση εισερχόμενων μηνυμάτων.
Όταν μεταφέρονται αντικείμενα μεταξύ απομονώσεων, πρέπει να είναι "μεταβιβάσιμα" (transferable), που περιλαμβάνει:
- Απλούς τύπους δεδομένων (int, double, String, bool)
- Λίστες και χάρτες που περιέχουν μεταβιβάσιμους τύπους
- Ορισμένους ειδικούς τύπους Flutter που μπορούν να σειριοποιηθούν
Αντικείμενα που δεν είναι μεταβιβάσιμα θα αντιγραφούν, και οι μελλοντικές αλλαγές σε ένα από αυτά δεν θα αντικατοπτρίζονται στο άλλο.
Βασικά σημεία:
- Οι απομονώσεις δεν μπορούν να έχουν άμεση πρόσβαση στη μνήμη η μία της άλλης.
- Δεν έχουν πρόσβαση σε κοινή κατάσταση, συμπεριλαμβανομένων μεταβλητών, κλάσεων και widget της κύριας απομόνωσης (UI-ροής).
- Η επικοινωνία μεταξύ απομονώσεων γίνεται ασύγχρονα.
- Στο Flutter, είναι σημαντικό να διαχειρίζεστε σωστά τον κύκλο ζωής των απομονώσεων (π.χ., χρησιμοποιώντας
isolate.kill()αν χρειάζεται).
Η χρήση απομονώσεων επιτρέπει την εκτέλεση μακροχρόνιων ή πόρων-εντατικών λειτουργιών στο παρασκήνιο, αποτρέποντας το πάγωμα του περιβάλλοντος χρήστη και διασφαλίζοντας ομαλή λειτουργία της εφαρμογής.