flutter 的线程模型
翻译https://buildflutter.com/flutter-threading-isolates-future-async-and-await/
flutter app 开始启动一个进程来执行代码。进程内,有不同的方式来同时执行不同的代码片段。
isolates
dart 启动的时候,将有一个main isolate(thread)。这个是app 的主要运行线程,也是主ui 线程。isolate 是:
- dart 版本的线程
- 彼此之间不共享内存
- 使用port 和 messages 来通信
- 可以的话,将使用其他的处理器核
- 并行执行代码
简单的flutter app 中只需要一个isolate。如果你有一个长时间运行的任务,isolate 是个不错的选择,app 的其他部分对此无感知。
事件循环 & 微任务(EventLoops & Microtasks)
event queue 是外部代码给当前isolate 提供处理请求的方法,是个先进先出的队列。
microtask queue 是当前isolate 异步执行代码的方法。microtask queue 优先于event loop 执行
Create new Isolate
import 'dart:isolate';
void mainApp() async {
var receivePort = new ReceivePort();
await Isolate.spawn(entryPoint, receivePort.sendPort);
// Receive the SendPort from the Isolate
SendPort sendPort = await receivePort.first;
// Send a message to the Isolate
sendPort.send("hello");
}
// Entry point for your Isolate
entryPoint(SendPort sendPort) async {
// Open the ReceivePort to listen for incoming messages (optional)
var port = new ReceivePort();
// Send messages to other Isolates
sendPort.send(port.sendPort);
// Listen for messages (optional)
await for (var data in port) {
// `data` is the message received.
}
}
Async & Await
- 在同一个Isolate 中执行
- 同一个Isolate 中并发执行
不阻塞同一个线程中的其他代码的执行。尤其是当你在主UI 线程中。将帮助你在保持UI 平滑运行的同时,并发处理更多的事件
Future
import 'dart:async';
Future myFunction() => new Future.value('Hello');
void main() {
myFunction().then((value) => debugPrint(value)); // Added to Microtask queue
myFunction().then((value) => debugPrint(value)); // Added to Microtask queue
someOtherFunction(); // Runs this code now
// Now starts running tasks from Microtask queue.
}
当调用myFunction ,该函数将被添加进Event Queue,在调用完someOtherFunction 后,myFunction 被执行。
当调用Future.delayed 或者 Future.value,将把任务投递到Microtask queue 中。
Async & Await
下面的代码,停止异步执行,直接等待异步任务的执行结果
void mainTest() async {
debugPrint(await myFunction()); // Waits for completion
debugPrint(await myFunction()); // Waits for completion
someOtherFunction(); // Runs this code
}
实际问题
https://medium.com/flutter-community/flutter-threading-5c3a7b0c065f
一旦一个dart 函数执行,知道它退出,不可能被同一个isolate的其他任务打断。
另一个介绍
https://web.archive.org/web/20170702213650/https://www.dartlang.org/tutorials/language/futures
介绍了future 相关的错误处理
https://web.archive.org/web/20170702215338/https://www.dartlang.org/articles/libraries/futures-and-error-handling
https://web.archive.org/web/20170704074724/https://webdev.dartlang.org/articles/performance/event-loop
这些介绍还是很好的,有很多细节,需要自己看了。
- microtask queue 是必要的,event-handing code 有时需要在之后完成一些任务,但需要在将执行权限返回给event loop 之前。
Future 相关的细节
- 传入then 的函数,在Future 完成之后,立马执行
- 如果在then 调用前,Future 已经完成了,该task 将被添加到microtask queue(task 执行then 中传入的函数)
- Future 和 Future.delayed() 构造函数,不立即完成,他们将任务添加到event queue中
- Future.value 构造函数,在一个microtask 中 完成 (类似2)
- Future.sync 构造函数,立即执行,并在一个microtask 中完成。(类似2)