はじめに
FlutterでiOSアプリを作っていて、処理中にIndicatorを回すような処理を書いていたが、
場所によっては、Indicatorが固まるような動きなるので、調べていたら、CPU負荷の高い処理によって、
スレッドがブロックしてしまうことが原因だった。
また忘れないように、以下覚書。
シングルスレッドのイベントループ
Dartの実行モデルはシングルスレッドのイベントループ処理(
https://qiita.com/takyam/items/6ad155678c95bba4047f
)で、Node.jsなどと同じ。
スレッドブロック
例1.
rei1.dart
await Future.delayed(new Duration(seconds: 5));
例2.
rei2.dart
await Future(() => sleep(new Duration(seconds: 5)));
この2つをcallしてみると、例1の方は、通常のasync awaitの書き方で次の処理に進むことが可能だが、
例2の場合は、スレッドをブロックしてしまうため、Futureを使って逃していても、
5秒間、アプリは止まってしまう。
単純にhttpのcallbackを待つ場合などはMain isolateを使い、シングルスレッド上で、実行させればokだが、
CPU負荷の高い処理などは、Main以外のIsolateで処理を行う必要がある。
compute関数を使う
FlutterではIsolateを簡単に扱うためにcomputeという関数が用意されているので、
これを呼べばOK.
call.dart
var result = await compute(testFunc,5);
注意点(Invalid argument(s): Illegal argument in isolate message )
"compute can only take top-level or static methods, but not instance methods"
ということで、
staticの関数でなければ呼び出せないらしい。