美文网首页
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