Flutter是否有并发List?如何解决List并发修改异常?
Flutter并发安全List相关问题解答
一、先解决你当前代码的报错
你现在的报错并非多线程并发导致,而是代码逻辑错误:channels.addAll(channels);这行把列表自身作为参数传入addAll,而addAll内部会遍历该列表,同时又向列表中添加元素,触发了迭代过程中修改列表的异常。
修正方案
如果是想把当前获取的列表元素复制一份添加到自身,需要先复制列表再添加:
void loadingMoreChannel(RefreshController _refreshController) async { articleRequest.pageNum = articleRequest.pageNum + 1; List<Channel> channels = await Repo.getChannels(articleRequest); // 先复制当前列表元素,再添加到自身 channels.addAll(List.from(channels)); _refreshController.loadComplete(); }
如果你的实际需求是把新获取的channels添加到另一个全局列表(比如代码中遗漏的_channels),则修正为操作目标列表:
// 假设存在全局列表 _channels void loadingMoreChannel(RefreshController _refreshController) async { articleRequest.pageNum = articleRequest.pageNum + 1; List<Channel> channels = await Repo.getChannels(articleRequest); _channels.addAll(channels); _refreshController.loadComplete(); }
二、Flutter中是否有内置的并发安全List?
Dart标准库没有内置的并发安全List,默认的List实现(比如_GrowableList)在多线程(Isolate)或多异步任务同时操作时,会出现数据竞争问题。
三、实现并发安全的List元素添加
如果是真正的多线程/多异步场景下需要保证List操作安全,可以用以下方式实现:
1. 使用互斥锁(Lock)
借助synchronized包(需在pubspec.yaml中添加依赖),通过锁保证同一时间只有一个操作能访问List:
import 'package:synchronized/synchronized.dart'; final Lock _lock = Lock(); List<Channel> _safeChannels = []; Future<void> addChannels(List<Channel> newChannels) async { await _lock.synchronized(() { _safeChannels.addAll(newChannels); }); }
2. 跨Isolate场景的处理
Dart中Isolate内存相互隔离,不能直接共享List,需通过SendPort和ReceivePort传递数据,或者在主Isolate中统一处理List修改操作,避免跨Isolate直接操作同一列表。
3. 自定义并发安全List封装
自己封装List类,用锁保护所有修改操作:
import 'package:synchronized/synchronized.dart'; class SafeList<T> { final List<T> _innerList = []; final Lock _lock = Lock(); Future<void> add(T element) async { await _lock.synchronized(() => _innerList.add(element)); } Future<void> addAll(Iterable<T> elements) async { await _lock.synchronized(() => _innerList.addAll(elements)); } // 按需实现其他方法,如remove、clear等,均用lock包裹 Future<List<T>> get copy async { return await _lock.synchronized(() => List.from(_innerList)); } }
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

