Flutter 92: 图解 Dart 单线程实现异步处理之 Isolate (一)

简介: 0 基础学习 Flutter,第九十二步:了解基本的 Isolate 用法 (一)!

      小菜刚尝试了 Futureasync-await 实现的简单异步操作,但对于耗时较长的异步该如何处理呢?对于 Android 来说可以新开一个线程单独处理,而对应的 Dart 可以用 Isolate 来处理;

Isolate

      Isolate 是对 Dart 并发模式的实现,类似于 Android 中的 Thread 线程,但与 Thread 有本质的区别,Thread 可以实现内存共享,而 Isolate 不能;

      所有的 Dart Code 都是在 Isolate 中执行的,代码只能使用同一个 Isolate 中的内容,Isolate 有自己的内存和事件循环机制;不同的 Isolate 是内存隔离的,因此只能通过 Port 机制发送消息通信,其原理是向不同的 Isolate 队列中执行写任务;

Isolate 的创建

      Isolate 一般通过 spawn / spawnUri 来创建对象;

Isolate.spawn()
external static Future<Isolate> spawn<T>(
  void entryPoint(T message), T message,
  {bool paused: false,
  bool errorsAreFatal,
  SendPort onExit,
  SendPort onError,
  @Since("2.3") String debugName});

      简单了解源码,spawn 必须的参数包括需要耗时操作的 entryPointT 任意类型的 message 数据,即 Isolate 中可以传递任意类型的数据;

_loadIsolateDate() async {
  await Isolate.spawn(_backgroundWork, ReceivePort().sendPort);
}

static _backgroundWork(SendPort sendPort) {
  sendPort.send('BackgroundWork -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
}
Isolate.spawnUri()
external static Future<Isolate> spawnUri(
  Uri uri,
  List<String> args,
  var message,
  {bool paused: false,
  SendPort onExit,
  SendPort onError,
  bool errorsAreFatal,
  bool checked,
  Map<String, String> environment,
  @Deprecated('The packages/ dir is not supported in Dart 2')
      Uri packageRoot,
  Uri packageConfig,
  bool automaticPackageResolution: false,
  @Since("2.3")
      String debugName});

      简单了解源码,spawnUri 需要三个必要参数,uri 为其他 Isolate 代码文件的路径;列表 args 为传递的参数列表,message 动态消息,一般是 SendPort

_loadIsolateDate03() async {
  ReceivePort receivePort = ReceivePort();
  await Isolate.spawnUri(new Uri(path: "./utils/second_isolate.dart"),
      ['params01, params02, params03'], receivePort.sendPort);
  receivePort.listen((val) => print('listen -> 【$val】'));
}

Isolate 的通讯

      Isolate 可以方便的利用多核 CPU 来处理耗时操作,因内存不共享,需要通过 Port 进行消息通讯;其中 Port 消息传递也是异步的;

单向通讯

      Port 一般是成对出现,分别是 ReceivePort 接收端口和 SendPort 发送端口;而 ReceivePort 也可以生成自己的 SendPort;只需要把 SendPort 传递给其他 Isolate 即可;

_loadIsolateDate01() async {
  ReceivePort receivePort = ReceivePort();
  await Isolate.spawn(_backgroundWork, receivePort.sendPort);
  receivePort.listen((val) => print('listen -> 【$val】'));
}

static _backgroundWork(SendPort sendPort) async {
  sendPort.send(
      'BackgroundWork -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
  Future.delayed(Duration(seconds: 3), () {
    return sendPort.send(
        'BackgroundWork delayed 3s -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
  });
}

双向通讯

      双向通讯与单向通讯一样,把双方的 SendPort 相互传递即可;

_loadIsolateDate02() async {
  ReceivePort receivePort = ReceivePort();
  var sendPort;
  await Isolate.spawn(_backgroundWork2, receivePort.sendPort);
  receivePort.listen((val) {
    if (val is SendPort) {
      sendPort = val as SendPort;
      print("双向通讯建立成功");
    }
    print("Isolate Recevie Data -> 【$val】");
    if (sendPort != null) {
      sendPort.send('_loadIsolateDate02 -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
    }
  });
}

static _backgroundWork2(SendPort sendPort) async {
  ReceivePort receivePort = new ReceivePort();
  receivePort.listen((val) {
    print("Background Isolate Receive Data -> 【$val]");
  });
  sendPort.send('BackgroundWork -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
  sendPort.send(receivePort.sendPort);
  Future.delayed(Duration(seconds: 2), () {
    return sendPort.send('BackgroundWork delayed 2s -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}');
  });
  Future.delayed(Duration(seconds: 5), () {
    return sendPort.send(receivePort.sendPort);
  });
}

Isolate 的销毁

      Isolate 就像机器中的一个小空间,有自己的内存块,因此在使用 Isolate 结束后应及时关闭并销毁当前 Isolate

isolate.kill(priority: Isolate.immediate);

Tips

Q:Invalid argument(s): Isolate.spawn expects to be passed a static or top-level function

      小菜刚开始创建 Isolate 时,遇到如下错误;

A:

      需要将 Isolate.spawn 中的 message 参数方法设置成 static 方法或放置在 main() 入口;


      由于篇幅和测试案例不足,小菜分为两篇小博客对 Isolate 进行学习,对异步的认知还不够深入;如有错误请多多指导!

来源: 阿策小和尚

目录
相关文章
|
4月前
|
监控 Dart 安全
创建一个Dart应用,监控局域网上网记录的软件:Flutter框架的应用
在当今数字时代,网络安全变得愈发重要。为了监控局域网上的上网记录,我们可以借助Flutter框架创建一个强大的Dart应用。在这篇文章中,我们将深入讨论如何使用Flutter框架开发这样一个监控局域网上网记录的软件,并提供一些实用的代码示例。
281 1
|
11天前
|
Dart 前端开发 安全
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
【4月更文挑战第30天】本文探讨了Flutter中线程管理和并发编程的关键性,强调其对应用性能和用户体验的影响。Dart语言提供了`async`、`await`、`Stream`和`Future`等原生异步支持。Flutter采用事件驱动的单线程模型,通过`Isolate`实现线程隔离。实践中,可利用`async/await`、`StreamBuilder`和`Isolate`处理异步任务,同时注意线程安全和性能调优。参考文献包括Dart异步编程、Flutter线程模型和DevTools文档。
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
|
11天前
|
Dart 前端开发 开发者
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
【4月更文挑战第30天】Dart是Google为Flutter框架打造的高效编程语言,具有易学性、接口、混入、抽象类等特性。本文概述了Dart的基础语法,包括静态类型(如int、String)、控制流程(条件、循环)、函数、面向对象(类与对象)和异常处理。此外,还介绍了库导入与模块使用,帮助开发者快速入门Flutter开发。通过学习Dart,开发者能创建高性能的应用。
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
|
12天前
|
Dart 测试技术 UED
Dart 和 Flutter 错误处理指南 | 最佳实践全解析
深入探索 Dart 和 Flutter 中的错误处理技术,从编译时错误到运行时异常,带你学习如何优雅地处理应用程序中的各种意外情况。了解最佳实践,让你的应用程序稳如磐石,用户体验持续优化!
Dart 和 Flutter 错误处理指南 | 最佳实践全解析
|
16天前
|
存储 缓存 开发框架
Flutter的网络请求:使用Dart进行HTTP请求的技术详解
【4月更文挑战第26天】了解Flutter网络请求,本文详述使用Dart进行HTTP请求
|
16天前
|
开发框架 Dart Java
Flutter的核心:Dart语言基础——语法与特性深度解析
【4月更文挑战第26天】Flutter框架背后的Dart语言,以其简洁的语法和独特特性深受开发者喜爱。本文深入解析Dart的语法与特性,如类型推导、动态静态类型系统、统一的类接口、访问权限控制以及并发编程支持。了解并掌握Dart,能助开发者更高效地利用Flutter构建高性能移动应用。
|
3月前
|
Dart JavaScript
Flutter - Dart 基础(数据类型)
【2月更文挑战第3天】
71 1
|
3月前
|
Dart JavaScript 安全
|
3月前
|
Dart Shell 开发工具
解决windows安装Flutter时出现Unknown operating system. Cannot install Dart SDK.问题
解决windows安装Flutter时出现Unknown operating system. Cannot install Dart SDK.问题
|
4月前
|
JSON Dart 算法
Dart/Flutter工具模块:the_utils
Dart/Flutter工具模块:the_utils
48 0