当前位置: 首页 > news >正文

dart中实现子isolate的管理类,特适用于针对数据库的处理

dart中的isolate已经困扰我好几天了,主要项目需要,比如对数据库的处理,都放到一个单独的子isolate(子线程)中,优势在于,当数据库足够大时,对数据库的处理可能较为耗时,这时,只用dart的主isolate,可能会对其他逻辑的处理,造成阻塞。可能有人说,await、async不就可以异步实现吗,异步操作和子线程操作还是有很大区别的。这篇可以用作了解学习

最开始接触isolate时,主子isolate发送接收port,很容易绕晕,不过,结合一些网上资料,加上这个简单的demo,有助于理解,希望能帮到一些和我一样,因刚接触isolate而头疼的人。至少让我豁然开朗了,也看到了自己思维的局限性,不够扩散开来。

代码贴出如下,由于没用到什么插件,所以,不会对使用插件版本过度依赖,亲测,可本机直接$ dart run运行,另外,这只是个demo,不涉及任何项目内容的东西,但你看明白了,应用起来会很迅速,特此记录。

import 'dart:isolate';

// 子 isolate 要执行的函数
void childIsolate(SendPort sendPort) async {
  // 创建一个 ReceivePort 来接收主 isolate 发送的数据
  ReceivePort receivePort = ReceivePort();

  // 将 ReceivePort 的 SendPort 发送给主 isolate
  sendPort.send(receivePort.sendPort);

  await for (var message in receivePort) {
    if (message is List && message.length > 3 && message[0] == 'insert') {
      print("childIsolate cur received: $message");
      SendPort responseSendPort = message[3];
      String table = message[1];
      String row = message[2];
      String ret = await DBUtils().insert(table, row);
      responseSendPort.send(ret);
    } else {
      print(": $message");
    }
  }
}

class IsolateService {
  static Isolate? _isolate;
  static SendPort? _childSendPort;
  static final ReceivePort _receivePort = ReceivePort();

  static Future<void> init() async {
    _isolate = await Isolate.spawn(childIsolate, _receivePort.sendPort);
    await for (var message in _receivePort) {
      if (message is SendPort) {
        _childSendPort = message;
        break;
      }
    }
  }

  static Future<dynamic> sendAndReceive(dynamic message) async {
    if (_childSendPort == null) {
      throw Exception('childIsolate is not initialized. Call init() first.');
    }
    final responseReceivePort = ReceivePort();// 作为当前主调子一次的返回,一次处理完成后,需要close,下次再调时,再创建
    _childSendPort!.send([...message, responseReceivePort.sendPort]);

    try {
      final response = await responseReceivePort.first;
      print("mainIsolate has get the response fron childIsolate: $response");
      responseReceivePort.close();
      return response;
    } catch (e) {
      print('Error receiving response: $e');
      return null;
    }
  }

  static void dispose() {
    _receivePort.close();
    _isolate?.kill(priority: Isolate.immediate);
  }
}

class DBUtils {
  Future<String> insert(String table, String row) async {// 模拟耗时任务
    for (int i = 0; i < 10; i++) {
      for (int j = 0; j < 100; j++) {
        for (int k = 0; k < 100; k++) {}
      }
    }
    return "ret from insert";
  }
}

void main() async {
  await IsolateService.init();

  // 第一个场景
  Future(() async {
    final response1 = await IsolateService.sendAndReceive(['insert', 'table1', 'row1']);
    print("Received response in first scenario: $response1");
  });

  // 第二个场景
  Future(() async {
    final response2 = await IsolateService.sendAndReceive(['insert', 'table2', 'row2']);
    print("Received response in second scenario: $response2");
  });

  // 模拟程序结束时释放资源
  await Future.delayed(Duration(seconds: 5));
  IsolateService.dispose();
}

相关文章:

  • 【js逆向】iwencai国内某金融网站实战
  • 心智模式—系统思考
  • 小白学Agent技术[1]
  • 初阶数据结构(C语言实现)——3.4带头双向循环链表详解(定义、增、删、查、改)
  • Android AudioFlinger(四)—— 揭开PlaybackThread面纱
  • ollama 安装方式
  • 九章云极 Aladdin重塑 AI 开发范式的先锋力量
  • Mybatis-Plus 插件机制与自定义插件实现
  • 分布式锁—6.Redisson的同步器组件
  • Tomcat之 配置https协议即SSL证书
  • 华为eNSP:配置单区域OSPF
  • 深入xtquant:实现高效量化交易的关键步骤
  • 用Ruby的Faraday库来进行网络请求抓取数据
  • 【ThreeJS Basics 09】Debug
  • 基于YOLO11深度学习的运动品牌LOGO检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】
  • cuda矩阵转置算子(共享内存)
  • Bean 的生命周期主要包括以下阶段:
  • CAD Voronoi V3.0.0多图层分区插件
  • PQL查询和监控各类中间件
  • NX二次开发,创建基准平面
  • 学院网站建设的目的/杭州seo推广排名稳定
  • 做网站界面需要注意什么/seo优化方案
  • 网站建设分工/购物网站页面设计
  • 深圳网站建设兼职/重庆seo小潘大神
  • 网站建设有关数据库的代码/独立站平台选哪个好
  • 网站建设及推广服务公司/企业网站怎么做