• asyncawait
    对于普通的任务,使用asyncawait可实现异步处理任务,而async的处理方式并非使用的是多线程,而是依然在UI线程中处理任务,是在同一个线程上的并发操作。
    对于比较繁重的处理任务,可使用compute来开启新isolate,来处理任务。

  • isolate
    是类似于线程,但不共享内存的独立的worker。是一个独立的dart程序执行环境。
    对于每一个flutter应用,当应用被启动时都会有一个默认的isolate,称为root isolate。我们自己的代码默认情况下都在这个isolate中执行。

dart中的isolate比较重量级,IsolateUI线程传输比较复杂,flutterfoundation中封装了一个轻量级的compute操作。

compute的使用还是有些限制,它没有办法多次返回结果,也没有办法持续性的传值计算,每次调用,相当于新建一个隔离,如果调用过多的话反而会适得其反。我们需要根据不同的业务选择用compute和isolate

  • compute使用条件:
    1、传入的方法只能是顶级函数或static函数
    2、只有一个传入参数和一个返回值

  • compute使用:

_count = await compute(countEven, 1000000000);

每次调用,都相当于创建了一个isolate,如果频繁使用的话,CPU性能、内存占用消耗也很大。

-isolate的使用:

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

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

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

  void test() async {
    myCount = await isolateCountEven(100, 2);
    setState(() {});
  }

  // 计算偶数的个数
  static int countEven(int num1, int num2) {
    int count = 0;
    while (num1 > 0) {
      if (num1 % 2 == 0) {
        count++;
      }
      num1--;

      num1 -= num2;
      print('$count');
    }
    return count;
  }

  static Future<dynamic> isolateCountEven(int num1, int num2) async {
    final response = ReceivePort();
    await Isolate.spawn(countEvent2, response.sendPort);

    final sendPort = await response.first;
    final answer = ReceivePort();
    sendPort.send([answer.sendPort, num1, num2]);
    return answer.first;
  }

  static void countEvent2(SendPort port) {
    final rPort = ReceivePort();
    port.send(rPort.sendPort);
    rPort.listen((message) {
      final send = message[0] as SendPort;
      final n1 = message[1] as int;
      final n2 = message[2] as int;
      send.send(countEven(n1, n2));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('$myCount'),
            MaterialButton(
              onPressed: test,
              child: Text('点击按钮'),
            ),
          ],
        ),
      ),
    );
  }
}
  • isolate使用优化:
    使用三方库isolate来创建isolate池,自动实现负载均衡。
    isolate: ^2.0.3

1、创建指定个数的isolate

Future<LoadBalancer> loadBalancer = LoadBalancer.create(2, IsolateRunner.spawn);

2、使用

int useLoadBalancer() async {
    final lb = await loadBalancer;
    int res = await lb.run<int, int>(_doSomething, 1);
    return res;
  }

每个isolate中执行顺序:
每次执行前先微任务队列判断有没有要处理,没有微任务再在event队列执行一个event任务,单个event任务处理完之后,再从头遍历微任务队列是否有新的微任务。

微任务包括:

创建微任务:

scheduleMicrotask((){
      print("微任务2");
    });

Flutter 事件机制 - Future 和 MicroTask 全解析

用Future还是isolate?

future使用场景:

  • 代码段可以独立运行而不会影响应用程序的流畅性

isolate使用场景:

  • 繁重的处理可能要花一些时间才能完成
  • 网络加载大图
  • 图片处理

Flutter 事件机制 - Future 和 MicroTask 全解析
flutter之-dart多线程isolate(二)

跟我学flutter:我们来举个例子通俗易懂讲解异步(二)ioslate循环机制_二蛋和他的大花的博客-CSDN博客flutter入门之理解Isolate及compute ——解决耗时操作卡住UI的问题_flutter 耗时操作_茉莲晨曦的博客-CSDN博客 

转载链接:https://www.jianshu.com/p/e27e5626b56f

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐