Isolate
在Dart中實現(xiàn)并發(fā)可以用Isolate宙攻,它是類似于線程(thread)但不共享內(nèi)存的獨立運行的worker,是一個獨立的Dart程序執(zhí)行環(huán)境堕担。其實默認環(huán)境就是一個main isolate已慢。
基本使用
library flutter_flutterisolate2;
import 'dart:async';
import 'dart:isolate';
main() async{
//1.創(chuàng)建一個和isoLate環(huán)境交流的Port
var receivePort = new ReceivePort();
//2.創(chuàng)建一個隔離isolate并且提供用于回執(zhí)的sendPort,receivePort.sendPort是一個給當前receive發(fā)消息的sendPort
await Isolate.spawn(speak, receivePort.sendPort);
//5.現(xiàn)在需要一個sendPort給isolate發(fā)送消息
SendPort sendPort = await receivePort.first;
//6. 利用sendPort給isoLate發(fā)送一個消息
var resultFromIsoLate = await sendMessage2IsoLate(sendPort, 'apple');
//8.打印來自于isolate的執(zhí)行結(jié)果
print(resultFromIsoLate);
resultFromIsoLate = await sendMessage2IsoLate(sendPort, 'banana');
print(resultFromIsoLate);
}
//3.創(chuàng)建用于在新isolate執(zhí)行的函數(shù)speak
speak(SendPort sendPort) async{
//4.現(xiàn)在提供給主isolate一個用于給子isolate發(fā)消息的sendPort
var receivePort = new ReceivePort();
sendPort.send(receivePort.sendPort);
//單次讀取
// var msgFromMainIsoLate = await receivePort.first;
// var msg = msgFromMainIsoLate[0];
// SendPort replyTo = msgFromMainIsoLate[1];
// replyTo.send("i like eat "+ msg);
//7. 讀取receivePort并且回傳消息, receivePort看起來是一個可迭代器
await for (var r in receivePort){
var msg = r[0];
SendPort replyTo = r[1];
replyTo.send("i like eat "+ msg);
}
}
//如果需要關(guān)閉,使用receivePort.close
//發(fā)送一條消息給isolate
Future sendMessage2IsoLate(SendPort sendPort, String msg) {
ReceivePort receivePort = ReceivePort();
sendPort.send([msg, receivePort.sendPort]);
return receivePort.first;
}
耗時計算解決案例(compute)
compute只能完成單次isolate交互霹购,無法支持佑惠,適合部分簡單場景
注意:web模式下似乎沒有效果!!!
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
class TestWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return TestWidgetState();
}
}
class TestWidgetState extends State<TestWidget> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: Column(
children: <Widget>[
Container(
width: 100,
height: 100,
child: CircularProgressIndicator(),
),
FlatButton(
onPressed: () async {
_count = countEven(1000000000);
setState(() {});
},
child: Text(
_count.toString(),
)),
],
mainAxisSize: MainAxisSize.min,
),
),
);
}
//計算偶數(shù)的個數(shù)
static int countEven(int num) {
int count = 0;
while (num > 0) {
if (num % 2 == 0) {
count++;
}
num--;
}
return count;
}
}
耗時異步為什么解決不了卡頓?
static Future<int> asyncCountEven(int num) async{
int count = 0;
while (num > 0) {
if (num % 2 == 0) {
count++;
}
num--;
}
return count;
}
仍然卡頓,說明異步是解決不了問題的齐疙,為什么膜楷?因為我們?nèi)耘f是在同一個UI線程中做運算,異步只是說我可以先運行其他的贞奋,等我這邊有結(jié)果再返回把将,但是,記住忆矛,我們的計算仍舊是在這個UI線程察蹲,仍會阻塞UI的刷新,異步只是在同一個線程的并發(fā)操作催训。
isolate解決方法
static Future<dynamic> isolateCountEven(int num) async {
final response = ReceivePort();
await Isolate.spawn(countEvent2, response.sendPort);
final sendPort = await response.first;
final answer = ReceivePort();
sendPort.send([answer.sendPort, num]);
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 n = message[1] as int;
send.send(countEven(n));
});
}