如何实现分组异步任务:同组最后任务等待前置任务且跨组任务并行
实现方案(完全可行)
核心思路
- 用Linq的
GroupBy按字母分组,每组内按版本号升序排序,拆分出非最后版本项和最后版本项。 - 直接启动所有跨组的非最后版本任务,让它们无依赖并行运行。
- 对每个组,单独等待本组所有非最后任务完成后,再启动该组的最后版本任务。
代码示例
先修正你给出的非法语法,定义合法的数据结构:
public record Item(char Group, int Version); var myStuff = new List<Item> { new('A', 1), new('A', 2), new('A', 3), new('B', 1), new('B', 2), new('C', 1), new('C', 2), new('C', 3), new('C', 4) };
然后实现核心逻辑:
// 分组并排序每组内的版本 var groupedItems = myStuff .GroupBy(item => item.Group) .Select(g => new { Group = g.Key, SortedItems = g.OrderBy(item => item.Version).ToList() }) .ToList(); // 存储全局非最后版本任务,以及每组的最后版本+对应前置任务 var globalNonFinalTasks = new List<Task>(); var groupFinalJobs = new List<(Item FinalItem, List<Task> PreTasks)>(); foreach (var group in groupedItems) { // 拆分本组的非最后项和最后项 var nonFinalItems = group.SortedItems.Take(group.SortedItems.Count - 1).ToList(); var finalItem = group.SortedItems.Last(); // 启动本组非最后任务,加入全局列表 var groupPreTasks = nonFinalItems.Select(item => Task.Run(() => { Console.WriteLine($"执行任务:{item.Group}:{item.Version}"); // 替换为你的任务逻辑,比如Thread.Sleep(1000)模拟耗时操作 })).ToList(); globalNonFinalTasks.AddRange(groupPreTasks); groupFinalJobs.Add((finalItem, groupPreTasks)); } // 启动所有组的最后任务(每个组的最后任务会等待本组前置任务完成) var finalTasks = groupFinalJobs.Select(async tuple => { await Task.WhenAll(tuple.PreTasks); Console.WriteLine($"执行任务:{tuple.FinalItem.Group}:{tuple.FinalItem.Version}"); // 替换为最后版本任务的逻辑 }).ToList(); // 等待所有任务完成 await Task.WhenAll(globalNonFinalTasks.Concat(finalTasks));
关键说明
- 所有非最后版本任务(A:1、A:2、B:1、C:1、C:2、C:3)会同时启动,跨组完全并行,无任何依赖限制。
- 每个组的最后版本任务(A:3、B:2、C:4)会严格等待本组其他任务全部完成后才执行,组之间的最后任务也会并行运行。
- 整个逻辑仅依赖Linq分组和Task异步等待机制,无需额外复杂组件。
内容的提问来源于stack exchange,提问作者pseudodev
相关产品推荐
相关产品推荐

