美文网首页
Flutter关于Isolate的初步学习应用

Flutter关于Isolate的初步学习应用

作者: 小源子2016 | 来源:发表于2021-04-01 18:47 被阅读0次
Isolate

在Dart中实现并发可以用Isolate,它是类似于线程(thread)但不共享内存的独立运行的worker,是一个独立的Dart程序执行环境。其实默认环境就是一个main isolate。

基本使用
library flutter_flutterisolate2;
import 'dart:async';
import 'dart:isolate';

main() async{
  //1.创建一个和isoLate环境交流的Port
 var receivePort = new ReceivePort();
 //2.创建一个隔离isolate并且提供用于回执的sendPort,receivePort.sendPort是一个给当前receive发消息的sendPort
 await Isolate.spawn(speak, receivePort.sendPort);
 //5.现在需要一个sendPort给isolate发送消息
  SendPort sendPort = await receivePort.first;
  //6. 利用sendPort给isoLate发送一个消息
  var resultFromIsoLate = await sendMessage2IsoLate(sendPort, 'apple');
  //8.打印来自于isolate的执行结果
  print(resultFromIsoLate);
  resultFromIsoLate = await sendMessage2IsoLate(sendPort, 'banana');
  print(resultFromIsoLate);
}

//3.创建用于在新isolate执行的函数speak
speak(SendPort sendPort) async{
  //4.现在提供给主isolate一个用于给子isolate发消息的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);
  }
}
//如果需要关闭,使用receivePort.close

//发送一条消息给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,
        ),
      ),
    );
  }
 
  //计算偶数的个数
  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;
  }

仍然卡顿,说明异步是解决不了问题的,为什么?因为我们仍旧是在同一个UI线程中做运算,异步只是说我可以先运行其他的,等我这边有结果再返回,但是,记住,我们的计算仍旧是在这个UI线程,仍会阻塞UI的刷新,异步只是在同一个线程的并发操作。

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));
    });
  }

参考资料
flutter入门之理解Isolate及compute

Dart - Isolate 并发

相关文章

网友评论

      本文标题:Flutter关于Isolate的初步学习应用

      本文链接:https://www.haomeiwen.com/subject/ofgtkltx.html