1

Is it possible to use multiple compute at the same time?

I'd like to call a heavy function on a list, which I want to run in parallel, but it crashes the app without any error message. Am I supposed to do only one compute call at a time?

Here's my test code that crashes often (but not always).

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: MyHomePage());
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Future<List<int>> f;

  @override
  void initState() {
    super.initState();
    f = getFutures();
  }

  Future<List<int>> getFutures() async {
    List<int> output = [];
    List<Future<int>> futures = [];
    for (int i = 0; i < 100; ++i) {
      print("call getFuture");
      futures.add(getFuture());
    }

    for (int i = 0; i < futures.length; ++i) {
      var f = await futures[i];
      output.add(f);
    }

    return output;
  }

  Future<int> getFuture() async {
    print("call compute");
    var i = await compute(count, 1000000000);
    return i;
  }

  static int count(int max) {
    print("start count");
    int j;
    for (int i = 0; i < max; ++i) {
      j = i;
    }
    return j;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("test")),
      body: FutureBuilder<List<int>>(
          future: f,
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.done:
                print(snapshot);
                return ListView.builder(
                    itemCount: 100,
                    itemBuilder: (context, index) {
                      return Text("snapshot: ${snapshot.data[index]}");
                    });
                break;
              default:
                return Center(child: CircularProgressIndicator());
            }
          }),
    );
  }
}
user987654
  • 5,461
  • 5
  • 23
  • 26
  • Please refer this answer :- https://stackoverflow.com/a/41470923/8884254 – Dhaval Patel Nov 12 '19 at 12:59
  • I can run them in serial, but I wonder if I can speed up by running them in parallel. – user987654 Nov 12 '19 at 13:01
  • `void multiCompute() { List futures = []; for (var i in [1, 5, 10]) { futures.add(compute(callback, i)); } Future.wait(futures).then((values) { print('all done: $values'); }); } FutureOr callback(int seconds) { print('start sleeping $seconds seconds'); sleep(Duration(seconds: seconds)); print('end sleeping $seconds seconds'); return seconds * seconds; }` – pskink Nov 12 '19 at 13:45
  • I changed [1,5,10] to length 100 list, sleep to some actual work, and still crashes. Is using multiple compute at the same time ok in flutter? – user987654 Nov 13 '19 at 01:20
  • 1
    it works for 100 concurrent `compute()`s too, but i dont think its a good idea to run 100 threads in parallel - if you got crash most likely your device went out of resources to create that many threads – pskink Nov 13 '19 at 06:15
  • 1
    and if you have multiple tasks to be run in background i would use `IsolateChannel` to communicate with a background `Isolate` – pskink Nov 13 '19 at 06:25
  • Thank you for the answer! I'll take a look at IsolateChannel – user987654 Nov 15 '19 at 03:34

0 Answers0