[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-gestione-asincrona-avanzata-in-flutter-isolates-e-compute-per-il-multithreading":3,"comments-article-gestione-asincrona-avanzata-in-flutter-isolates-e-compute-per-il-multithreading":21},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"video_url":10,"status":11,"published_at":12,"meta_title":13,"meta_description":14,"category":15,"author":19},17,"Gestione asincrona avanzata in Flutter: Isolates e compute per il multithreading","gestione-asincrona-avanzata-in-flutter-isolates-e-compute-per-il-multithreading","Scopri come usare gli Isolates di Dart e la funzione compute per eseguire operazioni pesanti senza bloccare l'interfaccia. Guida pratica con esempi reali e best practice.","## Introduzione\n\nFlutter e Dart sono single-threaded per natura: tutto il codice gira di default sul **main isolate**, lo stesso che gestisce il rendering dell'interfaccia. Quando esegui un'operazione computazionalmente pesante (parsing di un grande JSON, elaborazione di immagini, calcoli matematici), rischi di bloccare il thread della UI, causando i temuti **jank** e frame rate sotto i 60 FPS.\n\nIn questo articolo vediamo come sfruttare gli **Isolates** di Dart per spostare il lavoro pesante su thread separati, mantenendo l'app fluida e reattiva.\n\n## Cos'è un Isolate\n\nA differenza dei thread tradizionali, gli Isolates di Dart **non condividono memoria**. Ogni Isolate ha il proprio heap e comunica con gli altri esclusivamente tramite scambio di messaggi (message passing). Questo modello elimina alla radice molti problemi tipici della concorrenza, come le race condition.\n\nPunti chiave:\n\n- Ogni Isolate ha la propria memoria e il proprio event loop.\n- La comunicazione avviene tramite `SendPort` e `ReceivePort`.\n- I dati scambiati vengono copiati (con alcune eccezioni come i `TransferableTypedData`).\n\n## La soluzione rapida: compute\n\nPer i casi più semplici, Flutter offre la funzione `compute`, una scorciatoia che crea un Isolate, esegue una funzione e restituisce il risultato.\n\n```dart\nimport 'package:flutter\u002Ffoundation.dart';\nimport 'dart:convert';\n\n\u002F\u002F La funzione deve essere top-level o statica\nList\u003CMap\u003CString, dynamic>> parseJson(String rawJson) {\n  final List\u003Cdynamic> parsed = jsonDecode(rawJson);\n  return parsed.cast\u003CMap\u003CString, dynamic>>();\n}\n\nFuture\u003Cvoid> caricaDati(String rawJson) async {\n  \u002F\u002F L'elaborazione avviene su un Isolate separato\n  final risultato = await compute(parseJson, rawJson);\n  print('Elementi caricati: ${risultato.length}');\n}\n```\n\n> **Attenzione:** la funzione passata a `compute` deve essere di livello superiore (top-level) o un metodo statico. Non può essere una closure che cattura variabili dal contesto, perché deve poter essere trasferita all'altro Isolate.\n\n## Quando usare compute\n\nUsa `compute` quando hai un'operazione **una tantum** che:\n\n- riceve un input,\n- produce un output,\n- non richiede comunicazione continua.\n\nEsempi tipici: parsing di JSON pesanti, decodifica di immagini, calcoli matematici complessi.\n\n## Isolates manuali per scenari complessi\n\nQuando hai bisogno di una comunicazione bidirezionale continua o di un Isolate che resta attivo a lungo, devi gestirlo manualmente con `Isolate.spawn`.\n\n```dart\nimport 'dart:isolate';\n\nFuture\u003Cvoid> avviaWorker() async {\n  final receivePort = ReceivePort();\n\n  \u002F\u002F Avvia un nuovo Isolate passando il SendPort\n  await Isolate.spawn(_isolateEntry, receivePort.sendPort);\n\n  \u002F\u002F Riceve il SendPort dall'Isolate per poter inviare messaggi\n  final sendPort = await receivePort.first as SendPort;\n\n  \u002F\u002F Comunicazione richiesta-risposta\n  final risposta = ReceivePort();\n  sendPort.send([42, risposta.sendPort]);\n\n  final risultato = await risposta.first;\n  print('Risultato dall\\'Isolate: $risultato');\n}\n\nvoid _isolateEntry(SendPort mainSendPort) {\n  final port = ReceivePort();\n  mainSendPort.send(port.sendPort);\n\n  port.listen((messaggio) {\n    final numero = messaggio[0] as int;\n    final replyPort = messaggio[1] as SendPort;\n    \u002F\u002F Lavoro pesante\n    final calcolo = numero * numero;\n    replyPort.send(calcolo);\n  });\n}\n```\n\n## Isolate.run: la novità di Dart 2.19+\n\nLe versioni recenti di Dart hanno introdotto `Isolate.run`, un'API più moderna ed ergonomica rispetto a `compute`, che supporta anche le closure (in modo limitato) e gestisce automaticamente la chiusura dell'Isolate.\n\n```dart\nFuture\u003Cint> calcolaPesante() async {\n  return await Isolate.run(() {\n    var somma = 0;\n    for (var i = 0; i \u003C 1000000000; i++) {\n      somma += i;\n    }\n    return somma;\n  });\n}\n```\n\nQuesto approccio è oggi consigliato per la maggior parte dei casi d'uso semplici nel codice puro Dart.\n\n## Best practice\n\n- **Misura prima di ottimizzare:** non spostare ogni operazione su un Isolate. La creazione di un Isolate ha un costo. Usali solo quando l'operazione supera i ~16ms.\n- **Minimizza i dati trasferiti:** poiché i dati vengono copiati, evita di passare strutture enormi avanti e indietro.\n- **Evita di accedere a plugin:** gli Isolate secondari non hanno accesso diretto ai binding della piattaforma. Le chiamate ai plugin vanno fatte sul main Isolate.\n- **Gestisci gli errori:** usa `try\u002Fcatch` all'interno della funzione e considera `Isolate.run` che propaga automaticamente le eccezioni.\n\n## Conclusione\n\nGli Isolates sono lo strumento giusto per mantenere fluida la UI di Flutter quando devi eseguire lavoro pesante. Per i casi semplici, `compute` e `Isolate.run` offrono un'API immediata; per scenari complessi con comunicazione continua, `Isolate.spawn` ti dà il pieno controllo. Ricorda sempre di misurare le performance per usare questi strumenti dove servono davvero.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002F46687bf9-434c-4c04-93ae-8d3bf71f5161.jpg",null,"published","2026-06-21T04:00:36+00:00","Isolates e compute in Flutter: multithreading pratico","Guida pratica agli Isolates di Dart e alla funzione compute in Flutter: esegui operazioni pesanti senza bloccare la UI. Esempi e best practice.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":16,"name":20},"Flutter Bot",[],1785219605328]