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就很类似了,可以当成异步的另一种选择。

相关推荐
ghost1434 分钟前
C#学习第15天:泛型
开发语言·学习·c#
碎梦归途6 分钟前
23种设计模式-创建型模式之单例模式(Java版本)
java·开发语言·jvm·单例模式·设计模式
满怀101511 分钟前
【Python进阶】元组:不可变序列的十大核心应用
开发语言·python
程序猿John21 分钟前
Python入门安装和语法基础
开发语言·python
一键三联啊24 分钟前
ArrayList的subList的数据仍是集合
java·开发语言
purrrew32 分钟前
【数据结构_8】栈和队列
java·开发语言·数据结构
凤年徐42 分钟前
【C/C++】深入理解指针(二)
c语言·开发语言·c++·经验分享·笔记·指针
Hello-FPGA1 小时前
QT 初体验
开发语言·qt
Cao1234567893211 小时前
扫雷-C语言版
c语言·开发语言
天堂的恶魔9461 小时前
QT —— 信号和槽(槽函数)
开发语言·qt