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

相关推荐
曹轲恒7 小时前
Java中断
java·开发语言
—Qeyser8 小时前
Flutter 颜色完全指南
android·flutter·ios
施棠海8 小时前
监听与回调的三个demo
java·开发语言
時肆4858 小时前
C语言造轮子大赛:从零构建核心组件
c语言·开发语言
奋斗的小青年!!8 小时前
Flutter跨平台开发鸿蒙应用实战:OA系统考勤打卡组件深度解析
flutter·harmonyos·鸿蒙
赴前尘8 小时前
golang 查看指定版本库所依赖库的版本
开发语言·后端·golang
de之梦-御风9 小时前
【C#.Net】C#开发的未来前景
开发语言·c#·.net
知乎的哥廷根数学学派9 小时前
基于数据驱动的自适应正交小波基优化算法(Python)
开发语言·网络·人工智能·pytorch·python·深度学习·算法
de之梦-御风9 小时前
【C#.Net】C#在工业领域的具体应用场景
开发语言·c#·.net
sunfove9 小时前
将 Python 仿真工具部署并嵌入个人博客
开发语言·数据库·python