如何运行带有返回值的多个异步任务?
解决方案
问题分析
你当前的代码中,调用handler.FetchData()时异步任务已经开始执行,无法实现“存储任务但不立即执行”的需求。要达成目标,需要将任务的创建逻辑和执行操作分离。
实现步骤
1. 存储待执行的任务逻辑
使用Func<Task<List<string>>>类型的集合保存任务的创建逻辑,而非直接保存已启动的Task实例。只有当你显式调用委托时,才会触发FetchData()的执行:
var results = new List<string>(); // 存储任务创建逻辑,而非已启动的Task var taskFactories = new List<Func<Task<List<string>>>>(); foreach (var c in classList) { // 若FetchData是每个c实例的方法,此处应改为c.FetchData而非handler.FetchData taskFactories.Add(() => handler.FetchData()); }
2. 并行执行所有任务并收集结果
遍历任务工厂列表启动所有任务,用Task.WhenAll等待全部任务完成,最后合并结果到results列表:
// 启动所有任务,生成Task数组 var tasks = taskFactories.Select(factory => factory()).ToArray(); // 等待所有任务执行完成 var allResults = await Task.WhenAll(tasks); // 将所有任务的结果合并到results列表 foreach (var taskResult in allResults) { results.AddRange(taskResult); }
完整代码示例
var results = new List<string>(); var taskFactories = new List<Func<Task<List<string>>>>(); foreach (var c in classList) { taskFactories.Add(() => handler.FetchData()); } // 启动并等待所有任务完成 var allResults = await Task.WhenAll(taskFactories.Select(f => f())); // 扁平化合并所有结果 results.AddRange(allResults.SelectMany(r => r));
关键说明
Func<Task<List<string>>>的作用是包装任务逻辑,确保任务不会在添加到集合时立即执行。Task.WhenAll会并行等待所有任务完成,相比逐个等待能大幅提升执行效率。SelectMany可直接将嵌套的List<string>结构扁平化,简化结果合并代码。
内容的提问来源于stack exchange,提问作者A-Fairooz
相关产品推荐
相关产品推荐

