0
点赞
收藏
分享

微信扫一扫

Dart中的任务执行队列和Isolate

云上笔记 2021-09-19 阅读 27
Flutter

任务执行队列

1、Dart任务的执行顺序

① 先执行MicroTask Queue中的MicroTask

MicroTask Queue执行完之后,执行Event Queue中的Event

③ 每次都会判断是否有新的MicroTask和新的Event,优先执行MicroTask

2、MicroTask创建方法

scheduleMicrotask(() {});

Future.microtask(() {});

3、Event创建方法

async异步方法属于Event


Isolate

1、什么是Isolate

字面意思是隔离,即每个Isolate是独立的,隔离的,内存不共享的。

官方文档或注释的一部分:

2、两种方式可以生成Isolate

Isolate.spawn

compute()

3、Isolate是如何实现内存隔离的

参考文章:Dart中的Isolate

这里的内存指的就是堆内存,每个Isolate的堆内存是随着Isolate的创建而初始化。

4、Isolate之间的通信

DartVM支持的消息数据类型为:

① 原始数类型,如nullbooldoubleintString

SendPort实例,比如ReceivePort().sendPort

③ 包含①和②的listmap,也可以嵌套

④ 在DartVM中,处于同一进程的2个Isolate,也可以发送自定义的Class实例对象,但dart2js编译器不可以。

5、创建Isolate示例

① 创建Isolate

② 准备获取发送过来的数据

③ 将2边sendPort进行绑定

④ 创建监听,监听那边发过来的数据和SendPort

⑤ 开始往那边发送数据和SendPort

⑥ 等待那边处理数据

⑦ 监听到了那边发过来的数据和SendPort

⑧ 用拿到的数据进行大量的计算

⑨ 开始大量计算

⑩ 将计算完的数据发到那边

import 'dart:async';
import 'dart:isolate';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          MaterialButton(
            color: Colors.red,
            onPressed: test,
            child: Text('测试'),
          ),
        ],
      ),
    );
  }

  void test() {
    asyncFibonacci(3).then((value) {
      print('执行:11'); // ----> 11. 拿到返回值
      print(value);
    });
    /*
    flutter: 执行:1
    flutter: 执行:2
    flutter: 执行:3
    flutter: 执行:4
    flutter: 执行:5
    flutter: 执行:6
    flutter: 执行:7
    flutter: 执行:8
    flutter: 执行:9
    flutter: 执行:9
    flutter: 执行:9
    flutter: 执行:9
    flutter: 执行:9
    flutter: 执行:10
    flutter: 执行:11
    flutter: 2
     */
  }

  /// 创建Isolate来计算斐波那契数列第n个数
  /// n从0开始
  Future<dynamic> asyncFibonacci(int n) async {
    /// 创建Isolate

    /// 创建一个ReceivePort
    /// Isolate所需参数,必须要有SendPort,SendPort需要ReceivePort创建
    final receivePort = ReceivePort();

    /// 第一个参数entryPoint:必须是一个顶层方法或静态方法
    /// 第二个参数message:通常初始化message包含一个sendPort
    print('执行:1'); // ----> 1. 创建Isolate
    await Isolate.spawn(_isolateTopLevelFunction, receivePort.sendPort);

    /// 获取sendPort来发送数据
    print('执行:2'); // ----> 2. 准备获取发送过来的数据
    final sendPort = await receivePort.first as SendPort;

    /// 接收消息的receivePort
    final answerReceivePort = ReceivePort();

    /// 发送数据
    print('执行:5'); // ----> 5. 开始往那边发送数据和SendPort
    sendPort.send([Calculate(count: n), answerReceivePort.sendPort]);

    /// 获取数据并返回
    print('执行:6'); // ----> 6. 等待那边处理数据
    return answerReceivePort.first;
  }
}

/// Isolate的顶级方法
void _isolateTopLevelFunction(SendPort sendPort) {
  final receivePort = ReceivePort();

  /// 绑定
  print('执行:3'); // ----> 3. 将2边sendPort进行绑定
  sendPort.send(receivePort.sendPort);

  /// 监听
  print('执行:4'); // ----> 4. 创建监听,监听那边发过来的数据和SendPort
  receivePort.listen((message) {
    print('执行:7'); // ----> 7. 监听到了那边发过来的数据和SendPort

    /// 获取数据并解析
    final data = message[0] as Calculate;
    final send = message[1] as SendPort;

    /// 返回结果
    print('执行:8'); // ----> 8. 用拿到的数据进行大量的计算
    int num = syncFibonacci(data.count);

    print('执行:10'); // ----> 10. 将计算完的数据发到那边
    send.send(num);
  });
}

/// 同步的斐波那契计算顶级方法
int syncFibonacci(int n) {
  print('执行:9'); // ----> 9. 开始大量计算
  return n < 2 ? n : syncFibonacci(n - 2) + syncFibonacci(n - 1);
}

class Calculate {
  int count;

  Calculate({required this.count});
}
举报

相关推荐

0 条评论