C#中拆分ConcurrentBag为指定长度的二维列表
优化ConcurrentBag拆分二维列表的实现
一、使用内置LINQ方法(.NET 6+)
从.NET 6开始,LINQ提供了Chunk扩展方法,可直接将序列按指定大小拆分,ConcurrentBag实现了IEnumerable<T>接口,因此可以直接利用这个方法简化代码:
private static readonly ConcurrentBag<object> bag = new(); public static void UpdateResult() { const int chunkSize = 100; List<List<object>> data = bag.Chunk(chunkSize) .Select(chunk => chunk.ToList()) .ToList(); }
Chunk方法会将原序列拆分为多个指定大小的数组,通过Select将每个数组转为List<object>,最终得到目标二维列表。
二、手动优化实现(兼容低版本.NET)
原代码存在严重问题:复用temp列表并调用Clear()后,之前添加到data的列表会被清空(因为是同一个引用)。以下是修复bug并优化后的手动实现:
private static readonly ConcurrentBag<object> bag = new(); public static void UpdateResult() { const int chunkSize = 100; List<List<object>> data = new(); List<object> currentChunk = new(); foreach (var item in bag) { currentChunk.Add(item); if (currentChunk.Count == chunkSize) { data.Add(currentChunk); currentChunk = new List<object>(); // 新建列表而非清空原列表,避免引用问题 } } // 处理最后一组不足指定长度的元素 if (currentChunk.Count > 0) { data.Add(currentChunk); } }
优化点说明:
- 用
foreach遍历替代手动操作枚举器,代码更简洁易读 - 当当前列表达到指定长度时,新建列表而非清空原列表,避免引用共享导致的数据丢失
- 用
const定义拆分长度,提升代码规范性
内容的提问来源于stack exchange,提问作者Rohit Pratap
相关产品推荐
相关产品推荐

