美文网首页一起来学Flutter~Flutter圈子Android 开发技术分享
Flutter 93: 图解 Dart 单线程实现异步处理之 I

Flutter 93: 图解 Dart 单线程实现异步处理之 I

作者: 阿策神奇 | 来源:发表于2020-07-03 19:38 被阅读0次

          小菜刚学习了 Isolate 的部分基本用法,今天继续尝试 compute 及其使用方式;

    Isolate

          小菜之前了解到 ReceivePortSendPort 是成对出现的,是 Isolate 之间唯一的消息通讯的方式;

    ReceivePort

    abstract class ReceivePort implements Stream {
      external factory ReceivePort();
    
      external factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort);
    
      StreamSubscription listen(void onData(var message),
          {Function onError, void onDone(), bool cancelOnError});
    
      void close();
    
      SendPort get sendPort;
    }
    

          简单分析源码可得,ReceivePort 中通过 get 获取一个 SendPort 对象,通过 SendPort 发送消息到 ReceivePort 中,之后再通过 listen 进行监听;

    SendPort

    abstract class SendPort implements Capability {
      void send(var message);
    
      bool operator ==(var other);
    
      int get hashCode;
    }
    

          SendPort 内容很简单,主要是通过 send 方法向 ReceivePort 传递消息;

    Compute

          小菜尝试了 Isolate 的基本用法,需要使用 ReceivePortSendPort 来进行消息通讯;而 Flutter 提供了更简单的 Compute Function

    源码分析

    Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { String debugLabel }) async {
      ...
      final Isolate isolate = await Isolate.spawn<_IsolateConfiguration<Q, FutureOr<R>>>(_spawn,
        _IsolateConfiguration<Q, FutureOr<R>>(
          callback, message,
          resultPort.sendPort,
          debugLabel, flow.id,
        ),
        errorsAreFatal: true,
        onExit: resultPort.sendPort,
        onError: errorPort.sendPort,
      );
      final Completer<R> result = Completer<R>();
      errorPort.listen((dynamic errorData) {
        ...
      });
      resultPort.listen((dynamic resultData) {
        ...
      });
      await result.future;
      Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id));
      resultPort.close();
      errorPort.close();
      isolate.kill();
      Timeline.finishSync();
      return result.future;
    }
    

          简单了解源码,Compute 实际是对 Isolate 的封装,Compute 是通过 Isolate.spawn() 方式来处理 Isolate 其中 compute() 方法中在通讯结束后自动进行 Isolate.kill() 销毁;且 compute() 直接返回内容,无需考虑 listen 监听等;

    案例尝试

          compute() 包含两个必填参数,第一个是定义新的 Isolate 的核心执行方法,第二个是函数对应的参数,可以是多个任意类型;因为 compute 实际是通过 Isolate.spawn() 来处理的,则对应的耗时方法也需要是在顶级 main 函数中或 static 方法;

    _loadIsolateDate04() async {
      print('main Isolate, current Isolate = ${Isolate.current.hashCode}');
      print(await compute(getName, ''));
    }
    
    static String getName(String name) {
      print('new Isolate, current Isolate = ${Isolate.current.hashCode}');
      sleep(Duration(seconds: 2));
      return '阿策小和尚';
    }
    

          对于 compute() 的异常处理,可以通过 try-catch 进行捕获;

    _loadIsolateDate05(bool isError) async {
      print('main Isolate, current Isolate = ${Isolate.current.hashCode}');
      try {
        print(await compute(_backgroundWork3, isError));
      } catch (e) {
        print(e);
      }
    }
    
    static _backgroundWork3(bool isError) async {
      print('new Isolate, current Isolate = ${Isolate.current.hashCode}');
      if (!isError) {
        return await Future.delayed(Duration(seconds: 2), () {
          return 'BackgroundWork delayed 2s -> currentTime -> ${DateTime.now().millisecondsSinceEpoch}';
        });
      } else {
        return await Future.error(ArgumentError.notNull('Input'));
      }
    }
    

          Isolate 案例尝试


          小菜对 Isolate 的源码还未深入研究,仅停留在应用层;如有错误请多多指导!

    来源: 阿策小和尚

    相关文章

      网友评论

        本文标题:Flutter 93: 图解 Dart 单线程实现异步处理之 I

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