Flutter 简化线程Isolate的使用

文章目录


前言

flutter的线程是数据独立的,每个线程一般通过sendport来传输数据,这样使得线程调用没那么方便,本文将提供一种支持lambda启动isolate的方法,且支持捕获值类型变量,以及支持返回值。


一、完整代码

由于代码量较少,原理就不介绍了,直接给出完整实现。

isolate_helper.dart

dart 复制代码
///在隔离中执行任务,只能捕获值,不能捕获引用或指针。
///需要注意成员方法中调用传lambda会自动捕获this,this中包含引用类型则不行,此时可修改为static方法中调用。
Future<T> isolateFuture<T>(T Function() isolateEntry) async {
  ReceivePort receivePort = ReceivePort();
  //创建一个Isolate相当于创建一个子线程
  await Isolate.spawn((message) {
    message.sendPort.send(message.isolateEntry());
  }, _IsolateMessage(isolateEntry, receivePort.sendPort));
  var ret = await receivePort.first as T;
  return ret;
}

class _IsolateMessage<T> {
  T Function() isolateEntry;
  SendPort sendPort;
  _IsolateMessage(this.isolateEntry, this.sendPort);
}

二、使用示例

1、通过lambda启动线程

dart 复制代码
void test() {
  String a = "hello word!";
  isolateFuture(() {
    //在子线程中执行任务,捕获(拷贝)了变量a。
    print("${Isolate.current.hashCode} $a");
  });
  print("${Isolate.current.hashCode} $a");
}

2、获取线程返回值

dart 复制代码
Future test1() async {
  String a = await isolateFuture(() {
    //在子线程中执行任务:略
    //返回结果
    return "hello word!";
  });
  print(a);
}

3、线程通信

dart 复制代码
void test2() {
  ReceivePort mainReceivePort = ReceivePort();
  SendPort isolateSendPort;
  mainReceivePort.listen((message) {
    //监听子线程的消息
    switch (message[0]) {
      case 0:
        print(message[1]);
        break;
      case 1:
        isolateSendPort = message[1];
        isolateSendPort.send([0, "hello word!"]);
        break;
    }
  });
  //sendport是可以直接捕获传给isolate的。
  final mainSendPort = mainReceivePort.sendPort;
  isolateFuture(() {
    //发送消息给主线程
    mainSendPort.send([0, "hello word!"]);
    ReceivePort isolateReceivePort = ReceivePort();
    isolateReceivePort.listen((message) {
      //监听主线程的消息
      switch (message[0]) {
        case 0:
          print(message[1]);
          break;
      }
    });
    //将sendPort发送到主线程,建立双向通信
    mainSendPort.send([1, isolateReceivePort.sendPort]);
  });
}

4、结束isolate

dart 复制代码
Future test1() async {
  String a = await isolateFuture(() {
    //isolate结束时建议手动kill,即此方法返回后isolate并不会结束,所以支持异步操作。返回后没有任何操作了gc似乎会清理isolate。
    Isolate.current.kill();
    return "hello word!";
  });
  print(a);
}

总结

以上就是今天要讲的内容,本文的提供线程启动方法,很大程度方便了使用,尤其是支持lambda,可以在任意上下文捕获变量开启线程,执行任务,并获取返回值,用法和Future就很类似了,可以当成异步的另一种选择。

相关推荐
YMWM_7 分钟前
第一章 Go语言简介
开发语言·后端·golang
只因在人海中多看了你一眼8 分钟前
python语言基础
开发语言·python
2401_8582861110 分钟前
101.【C语言】数据结构之二叉树的堆实现(顺序结构) 下
c语言·开发语言·数据结构·算法·
y250811 分钟前
《Object类》
java·开发语言
小技与小术15 分钟前
数据结构之树与二叉树
开发语言·数据结构·python
Summer不秃29 分钟前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰33 分钟前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
sunly_34 分钟前
Flutter:AnimatedSwitcher当子元素改变时,触发动画
flutter
AiFlutter35 分钟前
Flutter封装Coap
flutter
hccee37 分钟前
C# IO文件操作
开发语言·c#