"threads" in Dart using Flutter for web
Asked Answered
S

2

12

I'm currently implementing a simulation for some mathematical problems. Since Flutter has such an easy way to create user interfaces and has web-support, I decided to use Flutter for this project. So far, everything works perfectly. The problem however is that in one simulation, each step takes some time to process (with problem size 128 it takes ~14 seconds) during which the whole user interface freezes. I found that this can be solved using isolates however this is not supported for web. Is there any other approach to tackle this?

Strychnic answered 23/3, 2021 at 9:56 Comment(5)
maybe have a look at async programming dart.dev/codelabs/async-awaitFerreous
@TinusJackson I tried that. The step of the problem is triggered by an onPressed, which executes an async function. This didn't prevent the GUI from freezing so I tried to make the functions called in this trigger to be async as well. Unfortunately, this has not helped, no matter how deep I go and make functions asyncStrychnic
@TinusJackson Async programming differs from multi-threading. In async programming your device call an async function and wait for it to provide the required result. There is no computation goin on in the background then. In multi-threading, your device calls the fucntions and starts doing computation in the background. Async functions work on the same UI thread whereas Isolates functions compute on a completely different threadSarita
@SarveshDalvi I am aware. Unfortunately, Isolates are not supported for web. Is there a way to prevent my GUI from freezing while a process computes in the background?Strychnic
@Albert You can refer the solution I have provided. You baiscally use html workers instead of isolatesSarita
S
2

https://dev.to/kyorohiro/isolate-at-flutter-for-web-28lg#:~:text=We%20could%20use%20isolate%20in,Use%20Worker%20instead%20of%20Isolate. This link will help. You can use workers which were used when isolates were not supported in dart.

This one too : https://github.com/deakjahn/flutter_isolate_web has a good example of it's implementation

Sarita answered 23/3, 2021 at 10:1 Comment(0)
S
0

My solution for desktop/web threads: https://pub.dev/packages/dart_thread

Web platform requires additional steps to compile the worker, but you need to do this in any case if you create a worker.

Example of usage:

import 'package:dart_thread/dart_thread.dart';

class TestThread extends DartThread {

  // Need to mapping Class to super.init,
  // because dart did not allow override a static method
  static TestThread newInstance() => TestThread();

  @override
  // only for web 
  messageToObject(message) {

    if (message is Map<String, dynamic>) {

      if (message['runtimeType'] == 'CustomClass') return CustomClass.fromJson(message);

    }

    return super.messageToObject(message);
  }

  @override
  Future<void> onExecute(Function(dynamic message) sendMessage) async {
    int counter = 0;
    while (true) {
      sendMessage(++counter);
      await Future.delayed(Duration(seconds: 1));
    }
  }

  @override
  Future<void> onGetMessage(message, Function(dynamic message) sendMessage) async {
    print('Receive message from main thread: $message');
    sendMessage(message);
  }

}

class CustomClass {
  final int i;
  final String s;
  final double d;

  CustomClass(this.i, this.s, this.d);

  String toString() {
    return '$i, $s, $d';
  }

  Map<String, dynamic> toJson() => {
    'runtimeType': 'CustomClass',
    'i': i,
    's': s,
    'd' : d,
  };

  CustomClass.fromJson(Map<String, dynamic> json) :
        i = json['i'],
        s = json['s'],
        d = json['d'];

}

void main() async {

  TestThread testThread1 = TestThread();
  TestThread testThread2 = TestThread();

  await testThread1.init(TestThread.newInstance, (message) {
    print('Receive message from testThread1: $message');
  });

  await testThread2.init(TestThread.newInstance, (message) {
    print('Receive message from testThread2: $message');
  });

  testThread1.sendMessage('echo');
  testThread2.sendMessage('echo');

  CustomClass customClass = CustomClass(1, '1', 1.0);
  testThread1.sendMessage(customClass);
  testThread2.sendMessage(customClass);

  await Future.delayed(Duration(seconds: 10));

  testThread1.deInit();
  testThread2.deInit();

}

Result in console:

flutter: Receive message from testThread1: 1
flutter: Receive message from main thread: echo
flutter: Receive message from main thread: echo
flutter: Receive message from testThread2: 1
flutter: Receive message from testThread2: echo
flutter: Receive message from testThread1: echo
flutter: Receive message from main thread: 1, 1, 1.0
flutter: Receive message from main thread: 1, 1, 1.0
flutter: Receive message from testThread1: 1, 1, 1.0
flutter: Receive message from testThread2: 1, 1, 1.0
flutter: Receive message from testThread1: 2
flutter: Receive message from testThread2: 2
flutter: Receive message from testThread1: 3
flutter: Receive message from testThread2: 3
flutter: Receive message from testThread1: 4
flutter: Receive message from testThread2: 4
flutter: Receive message from testThread1: 5
flutter: Receive message from testThread2: 5
flutter: Receive message from testThread1: 6
flutter: Receive message from testThread2: 6
flutter: Receive message from testThread1: 7
flutter: Receive message from testThread2: 7
flutter: Receive message from testThread1: 8
flutter: Receive message from testThread2: 8
flutter: Receive message from testThread1: 9
flutter: Receive message from testThread2: 9
flutter: Receive message from testThread1: 10
flutter: Receive message from testThread2: 10
flutter: Receive message from testThread1: 11
Sarver answered 5/11, 2023 at 18:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.