Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using Isolate to call a function

I am running a test on using isolate to call function, below is my code

import 'dart:isolate';

import 'package:flutter/material.dart';

void main() async {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final result = await startDownloadUsingRunMethod();
          print('Factorial result: $result');
        },
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }


  Future<String> startDownloadUsingRunMethod() async {
    final imageData = await Isolate.run(_readAndParseJsonWithoutIsolateLogic);
    return imageData;
  }

  Future<String> _readAndParseJsonWithoutIsolateLogic() async {
    await Future.delayed(const Duration(seconds: 2));
    return 'this is downloaded data';
  }
}

everytime when I tap on my floatingActionButton to run the function I will get the error below

E/flutter ( 9611): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: object is unsendable – Library:’dart:async’ Class: _AsyncCompleter@4048458 (see restrictions listed at SendPort.send() documentation for more information)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

anyone know what cause these issues?

>Solution :

Isolate.run is used for isolates, which run in a separate isolate and do not support async/await operations directly.

To fix this issue, you can use Isolate.spawn to run a function in a separate isolate and then use a ReceivePort to communicate between the main isolate and the spawned isolate. Here’s how you can modify your code to achieve this:

floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final result = await startDownloadUsingSpawn();
          print('Download result: $result');
        },
        tooltip: 'Download',
        child: const Icon(Icons.download),
      ),
    );

Future<String> startDownloadUsingSpawn() async {
    final receivePort = ReceivePort();
    await Isolate.spawn(_readAndParseJsonWithoutIsolateLogic, receivePort.sendPort);

    final completer = Completer<String>();
    receivePort.listen((data) {
      completer.complete(data);
      receivePort.close();
    });

    return completer.future;
  }

static void _readAndParseJsonWithoutIsolateLogic(SendPort sendPort) async {
    await Future.delayed(const Duration(seconds: 2));
    final result = 'This is downloaded data';
    sendPort.send(result);
  }
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading