写点什么

【Flutter 专题】93 图解 Dart 单线程实现异步处理之 Isolate (二)

发布于: 1 小时前
【Flutter 专题】93 图解 Dart 单线程实现异步处理之 Isolate (二)

      小菜刚学习了 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 的源码还未深入研究,仅停留在应用层;如有错误请多多指导!


来源: 阿策小和尚

发布于: 1 小时前阅读数: 3
用户头像

还未添加个人签名 2021.05.13 加入

Android / Flutter 小菜鸟~

评论

发布
暂无评论
【Flutter 专题】93 图解 Dart 单线程实现异步处理之 Isolate (二)