【Flutter】Dart:Isolate

在 Dart 和 Flutter 中,所有的代码默认都运行在单一的线程(即主线程)上,这个线程也叫做 UI 线程。当进行耗时操作(如复杂计算或网络请求)时,如果不使用多线程处理,主线程会被阻塞,导致应用界面卡顿、无响应,影响用户体验。为了解决这个问题,Dart 提供了 Isolate,一种独立的执行单元,可以并行执行任务。

本教程将深入介绍 Dart 中的 Isolate,涵盖其含义、事件循环、消息传递机制以及如何在不同 Isolate 之间进行通信。

什么是 Isolate

在 Dart 中,Isolate 是一种独立的执行单元,它和线程的概念相似,但与传统的多线程不同。每个 Isolate 都拥有独立的内存堆和事件循环,因此 Isolate 之间不能直接共享内存,而是通过消息传递进行通信。由于隔离的内存管理,Isolate 能够有效避免多线程中的竞态条件和数据竞争问题。

单线程与 Isolate 的区别

  • 单线程:Dart 默认在单一线程上运行任务。单线程模型避免了复杂的线程同步问题,但在处理耗时任务时会阻塞主线程,影响应用的响应性。

  • Isolate:Isolate 是独立的执行单元,能够并行处理任务。每个 Isolate 都有自己的内存空间,不与其他 Isolate 共享数据,因此不会出现线程竞争问题。

示例:传统单线程任务阻塞

void main() {print('Start');// 模拟耗时任务for (int i = 0; i < 1000000000; i++) {}print('End');
}

在上述代码中,耗时任务会阻塞主线程,导致应用无法响应用户操作。为了解决这种问题,可以使用 Isolate 来将任务移出主线程。

Isolate 的事件循环与并行执行

每个 Isolate 都有自己的 事件循环,负责管理消息队列并处理异步任务。Dart 中的异步操作(如 FutureStream)也都是通过事件循环来调度的。当一个 Isolate 接收到消息时,它会将消息放入事件队列,并在合适的时机进行处理。

如何创建 Isolate

可以通过 Isolate.spawn() 来创建新的 Isolate。该方法会启动一个新的 Isolate,并执行指定的任务。

示例:创建 Isolate

import 'dart:isolate';void isolateTask(String message) {print('Isolate received: $message');
}void main() {print('Main isolate: Start');// 启动新的 IsolateIsolate.spawn(isolateTask, 'Hello from Main isolate');print('Main isolate: End');
}

输出:

Main isolate: Start
Main isolate: End
Isolate received: Hello from Main isolate

在这个例子中,我们使用 Isolate.spawn() 创建了一个新的 Isolate,运行 isolateTask() 函数,同时将消息传递给新的 Isolate。可以看到主线程不会等待 Isolate 的完成,而是继续执行后续代码。

Isolate 之间的消息传递

由于 Isolate 之间不能共享内存,因此它们只能通过 消息传递 进行通信。Dart 提供了 SendPortReceivePort 来在不同 Isolate 之间传递消息。

  • ReceivePort:接收消息的端口,类似于消息队列。
  • SendPort:发送消息的端口,通过 SendPort 可以向另一个 Isolate 发送消息。

创建消息传递机制

首先需要在主 Isolate 创建一个 ReceivePort,并将 SendPort 传递给新的 Isolate。新的 Isolate 可以通过 SendPort 发送消息,主 Isolate 使用 ReceivePort 来接收消息。

示例:主 Isolate 和子 Isolate 间的消息传递

import 'dart:isolate';void isolateTask(SendPort sendPort) {// 向主 Isolate 发送消息sendPort.send('Message from Isolate');
}void main() async {// 创建用于接收消息的 ReceivePortReceivePort receivePort = ReceivePort();// 启动新的 Isolate,并传递 SendPortawait Isolate.spawn(isolateTask, receivePort.sendPort);// 监听来自 Isolate 的消息receivePort.listen((message) {print('Main isolate received: $message');});
}

输出:

Main isolate received: Message from Isolate

在这个例子中,我们创建了一个 ReceivePort,并将它的 SendPort 传递给新的 Isolate。子 Isolate 使用 sendPort.send() 发送消息,主 Isolate 则通过 receivePort.listen() 接收并处理消息。

Isolate 双向通信

除了子 Isolate 向主 Isolate 发送消息之外,主 Isolate 也可以向子 Isolate 发送消息。这需要双向的 SendPortReceivePort,实现双向通信。

实现双向通信

在双向通信中,主 Isolate 和子 Isolate 都有各自的 SendPortReceivePort,相互之间可以发送和接收消息。

示例:双向通信

import 'dart:isolate';// 子 Isolate 任务,接收消息并回复
void isolateTask(SendPort mainSendPort) {// 创建子 Isolate 的接收端口ReceivePort isolateReceivePort = ReceivePort();// 向主 Isolate 发送子 Isolate 的 SendPortmainSendPort.send(isolateReceivePort.sendPort);// 监听来自主 Isolate 的消息isolateReceivePort.listen((message) {print('Isolate received: $message');// 回复主 IsolatemainSendPort.send('Reply from Isolate');});
}void main() async {// 创建主 Isolate 的接收端口ReceivePort mainReceivePort = ReceivePort();// 启动子 Isolate,并传递主 Isolate 的 SendPortawait Isolate.spawn(isolateTask, mainReceivePort.sendPort);// 监听来自子 Isolate 的消息mainReceivePort.listen((message) {if (message is SendPort) {// 收到子 Isolate 的 SendPort,向其发送消息SendPort isolateSendPort = message;isolateSendPort.send('Hello from Main isolate');} else {print('Main isolate received: $message');}});
}

输出:

Isolate received: Hello from Main isolate
Main isolate received: Reply from Isolate

在这个示例中,主 Isolate 和子 Isolate 都有自己的 ReceivePortSendPort。主 Isolate 将自己的 SendPort 传递给子 Isolate,子 Isolate 通过该 SendPort 发送消息回复主 Isolate。实现了双向的通信。

Isolate 的常见使用场景

耗时计算

在复杂的计算任务(如图像处理、大数据计算等)中使用 Isolate 可以避免阻塞 UI 线程。

示例:耗时任务

import 'dart:isolate';// 耗时任务
void computeTask(SendPort sendPort) {int sum = 0;for (int i = 0; i < 100000000; i++) {sum += i;}sendPort.send(sum);
}void main() async {ReceivePort receivePort = ReceivePort();// 启动 Isolate 执行耗时任务await Isolate.spawn(computeTask, receivePort.sendPort);// 获取计算结果receivePort.listen((result) {print('Sum: $result');});
}

在这个例子中,计算任务被移到子 Isolate 中执行,主线程不会被阻塞,从而保证了应用的流畅性。

网络请求并发处理

通过 Isolate 可以并行处理多个网络请求,提升网络任务的处理效率。

总结

Isolate 是 Dart 中一种重要的并行执行机制,适用于需要处理复杂计算或长时间执行任务的场景。与传统的多线程不同,Isolate 之间通过消息传递进行通信,避免了数据竞争和线程同步问题。在 Flutter 开发中,合理使用 Isolate 可以提高应用的性能和用户体验,确保长时间任务不会阻塞主线程。

掌握 Isolate 的使用,包括事件循环、消息传递和双向通信,可以帮助你构建高性能、响应迅速的应用。在实际开发中,Isolate 主要用于耗时操作、并发任务以及后台数据处理等场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/56628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【实战篇】用SkyWalking排查线上[xxl-job xxl-rpc remoting error]问题

一、组件简介和问题描述 SkyWalking 简介 Apache SkyWalking 是一个开源的 APM&#xff08;应用性能管理&#xff09;工具&#xff0c;专注于微服务、云原生和容器化环境。它提供了分布式追踪、性能监控和依赖分析等功能&#xff0c;帮助开发者快速定位和解决性能瓶颈和故障。…

【机器学习(十三)】零代码开发案例之股票价格预测分析—Sentosa_DSML社区版

文章目录 一、背景描述二、Sentosa_DSML社区版算法实现(一) 数据读入(二) 特征工程(三) 样本分区(四) 模型训练和评估(五) 模型可视化 三、总结 一、背景描述 股票价格是一种不稳定的时间序列,受多种因素的影响。影响股市的外部因素很多,主要有经济因素、政治因素和公司自身因素…

PHP获取图片属性(size, width, 和 height)的函数

在PHP中&#xff0c;要获取图片的尺寸&#xff08;宽度和高度&#xff09;&#xff0c;你可以使用 getimagesize() 函数。这个函数不仅返回图片的宽度和高度&#xff0c;还返回图片的类型和MIME类型等信息。 以下是 getimagesize() 函数的基本用法&#xff1a; <?php /…

云原生-降本增效最佳案例分享-学习笔记

云原生&#xff08;以技术为“内核”&#xff0c;一个核心的位置&#xff09;产业发展态势分析&#xff0c;云原生&#xff08;运维和研发测&#xff09;国内发展迅猛2021年市场的规模已经达到了千亿元&#xff0c;企业对云原生的投入和支出&#xff01;不同行业对于云原生的重…

ASP.NET Core8.0学习笔记(二十)——EFCore导航属性与外键

一、什么是实体间关系 数据库表&#xff08;实体&#xff09;之间的关系&#xff1a;一对一&#xff08;学生-成绩&#xff09;、一对多&#xff08;学生-科目&#xff09;、多对多&#xff08;教师-班级&#xff09;。数据库中&#xff0c;每一个实体可以由主键唯一标识&…

数据挖掘示例

案例背景&#xff0c;有公司进行橡胶玩具的生产&#xff0c;一共生产两种产品&#xff0c;分别为橡皮鱼和橡皮鸭。 已知条件为&#xff1a; 1、公司的橡胶原材料能够生产500只橡皮鸭或者400条橡皮鱼。 2、生产效率为公司产量不会高于400只橡皮鸭和300条橡皮鱼。 3、每只橡皮…

MySQL表的基本查询下/分组聚合统计

1&#xff0c;update 对查询到的结果进行列值更新&#xff0c;可以和older by&#xff0c;where&#xff0c;limit合并使用&#xff0c;为了方便讲解&#xff0c;将会以题目练习的方式进行说明&#xff1a; 1&#xff0c;将孙悟空同学的数学成绩变更为 80 分 本道题和where联…

动态规划(1)斐波那契数列模型

动态规划算法流程&#xff1a; 1、状态表示&#xff1a; 指的是dp&#xff08;dynamic programming&#xff09;表里面的值所表示的含义 如何得出&#xff1a;1、题目要求 2、经验题目要求 3、分析问题的过程中发现重复子问题 2、状态转移方程 dp[i]等于什么 3、初始化 保证…

dbt doc 生成文档命令示例应用

DBT提供了强大的命令行工具&#xff0c;它使数据分析师和工程师能够更有效地转换仓库中的数据。dbt的一个关键特性是能够为数据模型生成文档&#xff0c;这就是dbt docs命令发挥作用的地方。本教程将指导您完成使用dbt生成和提供项目文档的过程。 dbt doc 命令 dbt docs命令有…

案例实践 | 以长安链为坚实底层,江海链助力南通民政打造慈善应用标杆

案例名称-江海链 ■ 实施单位 中国移动通信集团江苏有限公司南通分公司、中国移动通信集团江苏有限公司 ■ 业主单位 江苏省南通市民政局 ■ 上线时间 2023年12月 ■ 用户群体 南通市民政局、南通慈善总会等慈善组织及全市民众 ■ 用户规模 全市近30家慈善组织&#…

查询hive数据库报错Required field ‘type‘ is unset

文章目录 一、报错内容TProtocolException: Required field ‘type’ is unset 一、报错内容TProtocolException: Required field ‘type’ is unset org.apache.thrift.protocol.TProtocolException: Required field ‘type’ is unset! Struct:TPrimitiveTypeEntry(type:nu…

leetcode二叉树(八)-二叉树的最大深度

题目 104.二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&…

C语言二级刷题

&#xff08;1&#xff09;考点9 &#x1f601; 1. #include <stdio.h> #define S(x) x*x #define T(x) S(x)*S(x) main() { int k5, j2;printf("%d,%d\n", S(kj),T(kj)); }本题考查宏定义 以kj直接代替x 则S(kj)kj*kj 2. #include <stdio.h> …

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波 前言MPU6050寄存器代码详解mpu6050.cmpu6050.h 使用说明 前言 本篇文章基于卡尔曼滤波的原理详解与公式推导&#xff0c;来详细的解释下如何使用卡尔曼滤波来解算MPU6050的姿态 参考资料&#xff1a;Github_mpu6050 MPU6050寄存器…

项目管理软件真的能让敏捷开发变得更简单吗?

敏捷开发是一种以快速交付和适应变化为核心特点的软件开发方法。其特点包括尽早并持续交付、能够驾驭需求变化、版本周期内尽量不加任务、业务与开发协同工作、以人为核心、团队配置敏捷等。 例如&#xff0c;尽早并持续交付可使用的软件&#xff0c;使客户能够更早地体验产品…

【算法篇】动态规划类(4)——子序列(笔记)

目录 一、Leetcode 题目 1. 最长递增子序列 2. 最长连续递增序列 3. 最长重复子数组 4. 最长公共子序列 5. 不相交的线 6. 最大子序和 7. 判断子序列 8. 不同的子序列 9. 两个字符串的删除操作 10. 编辑距离 11. 回文子串 12. 最长回文子序列 二、动态规划总结 …

[Linux#67][IP] 报头详解 | 网络划分 | CIDR无类别 | DHCP动态分配 | NAT转发 | 路由器

目录 一. IP协议头格式 学习任何协议前的两个关键问题 IP 报头与有效载荷分离 分离方法 为什么需要16位总长度 如何交付 二. 网络通信 1.IP地址的划分理念 2. 子网管理 3.网络划分 CIDR&#xff08;无类别域间路由&#xff09; 目的IP & 当前路由器的子网掩码 …

外包干了3周,技术退步太明显了。。。。。

先说一下自己的情况&#xff0c;大专生&#xff0c;21年通过校招进入武汉某软件公司&#xff0c;干了差不多3个星期的功能测试&#xff0c;那年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我才在一个外包企业干了3周的功…

C++11标准 future异步线程库

原文链接&#xff1a;C11标准 future异步线程库 前言 c标准有很多的版本,比较知名的如c98是第一版c标准,提供了c最底层的支持. 后面的c11和c20每个版本都会给c带来新特性. 而线程就是是c11最重要的特性. 虽然c98有pthread库,但是c11的thread有更好的跨平台能力,最重要的是c1…

神经网络构建与训练深度学习模型全过程(PyTorch TensorFlow)

神经网络构建与训练深度学习模型全过程&#xff08;PyTorch & TensorFlow&#xff09; 目录 &#x1f517; 什么是神经网络&#xff1a;基础架构与工作原理&#x1f9e9; 构建简单的神经网络&#xff1a;层次结构与激活函数&#x1f680; 前向传播&#xff1a;神经网络的…