Flutter进阶:高内存任务的动态并发执行完美实现

一、需求来源

flutter 项目中会遇到多文件上传或者下载之类的批量执行任务就需要控制并发数量(避免内存爆炸或者数据传输效率过差),今天灵光一闪,实现一个极简的,分享给大家。

内存爆炸: 一般表现为app闪退。

数据传输效率过差:一般表现为并发数量较多时,每个任务的速度都很慢,减少并发数可以显著提升速度(上传下载同理)。

二、使用示例

复制代码
假设任务总数是 10,最大并发是 3,每个任务耗时 1 秒完成,执行过程如下:

》执行任务0
》执行任务1
》执行任务2
》任务0 完成,3开始
》任务1 完成,4开始
》任务2 完成,5开始
》任务3 完成,6开始
》任务4 完成,7开始
》任务5 完成,8开始
》任务6 完成,9开始
》任务7 完成
》任务8 完成
》任务9 完成

三、源码

dart 复制代码
import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:flutter_templet_project/extension/dlog.dart';
import 'package:get/get.dart';

class ConcurrentExecutorDemo extends StatefulWidget {
  const ConcurrentExecutorDemo({
    super.key,
    this.arguments,
  });

  final Map<String, dynamic>? arguments;

  @override
  State<ConcurrentExecutorDemo> createState() => _ConcurrentExecutorDemoState();
}

class _ConcurrentExecutorDemoState extends State<ConcurrentExecutorDemo> {
  final scrollController = ScrollController();

  Map<String, dynamic> arguments = Get.arguments ?? <String, dynamic>{};

  /// 任务数
  var taskCount = 10;

  /// 并发数量
  var maxConcurrent = 3;

  /// 执行描述
  final descVN = ValueNotifier("");

  String get timeStr => DateTime.now().toString();

  @override
  void didUpdateWidget(covariant ConcurrentExecutorDemo oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("$widget"),
      ),
      body: buildBody(),
    );
  }

  Widget buildBody() {
    return Scrollbar(
      controller: scrollController,
      child: SingleChildScrollView(
        controller: scrollController,
        child: Column(
          children: [
            Text("并发执行(总数:$taskCount, 最大并发数: $maxConcurrent):"),
            ElevatedButton(onPressed: onTest, child: Text("开始执行")),
            ValueListenableBuilder(
              valueListenable: descVN,
              builder: (context, value, child) {
                return Text(value);
              },
            ),
          ],
        ),
      ),
    );
  }

  Future<void> onTest() async {
    descVN.value = "";

    final executor = ConcurrentExecutor(maxConcurrent: maxConcurrent);

    for (var i = 0; i < taskCount; i++) {
      final id = i;
      executor.add(() async {
        DLog.d('Start $id');
        descVN.value += "[$timeStr]Start $id\n";
        await Future.delayed(Duration(seconds: 1));
        DLog.d('Done $id');
        descVN.value += "[$timeStr]Done $id\n";
      });
    }

    await executor.waitForEmpty();
    DLog.d('All tasks complete');
    descVN.value += "[$timeStr]All tasks complete";
  }
}

/// 并发执行器
class ConcurrentExecutor {
  ConcurrentExecutor({this.maxConcurrent = 3});

  final int maxConcurrent;
  final Queue<Future<void> Function()> _taskQueue = Queue();
  int _running = 0;

  void add(Future<void> Function() task) {
    _taskQueue.add(task);
    _tryExecuteNext();
  }

  void _tryExecuteNext() {
    while (_running < maxConcurrent && _taskQueue.isNotEmpty) {
      final task = _taskQueue.removeFirst();
      _running++;
      task().whenComplete(() {
        _running--;
        _tryExecuteNext();
      });
    }
  }

  Future<void> waitForEmpty() async {
    while (_taskQueue.isNotEmpty || _running > 0) {
      await Future.delayed(Duration(milliseconds: 50));
    }
  }
}

最后、总结

1、本质上任务管理类实现一个任务队列,根据当前任务执行情况,在限定最大并发数的前提开启新任务,直到清空队列任务的动态过程管理。多用于任务(可能会占用高内存)且多数量(可能导致内存爆炸),和线程池中线程复用是同一个原理。也算是软件开发中具体场景的唯一真解,属于中高阶软件开发展必须掌握的技能。

2、典型场景:批量音视频上传下载,云盘同步等

github

相关推荐
kyriewen5 分钟前
奥特曼借GPT-5.5干杯,而你的Copilot正按Token收钱
前端·github·openai
AC赳赳老秦9 分钟前
投标合规提效:用 OpenClaw 实现标书 / 合同自动审核、关键词校验、格式优化,降低废标风险
开发语言·前端·python·eclipse·emacs·deepseek·openclaw
kyriewen16 分钟前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式
千寻girling1 小时前
《 Git 详细教程 》
前端·后端·面试
之歆2 小时前
DAY08_CSS浮动与行内块布局实战指南(下)
前端·css
yqcoder2 小时前
CSS Position 全解析:5 种定位模式详解
前端·css
Rhi6373 小时前
从零搭建项目:React 19 + Vite 8 + Tailwind CSS v4 实战配置
前端
竹林8183 小时前
用Viem替代ethers.js:从一次签名失败到完整迁移的实战记录
前端·javascript
之歆3 小时前
DAY08_CSS浮动与行内块布局实战指南(上)
前端·css
liulian09163 小时前
Flutter for OpenHarmony 跨平台开发:单位转换功能实战指南
flutter