C#如何同时运行多个Task并将返回值添加到同一列表?
问题原因
- 你声明的
List<dynamic>实际存入的是Task<dynamic>任务对象,而非任务完成后的返回结果 - 主进程在所有异步任务调度执行前就已经退出,没有等待任务执行的逻辑,因此不会发起网络请求也拿不到返回值
- 网络请求属于IO密集型操作,你用
Task.Factory.StartNew包裹同步DownloadString的写法会浪费线程资源,推荐使用原生异步API实现
最简实现方案
使用Task.WhenAll即可一键等待所有并行任务完成,批量获取所有返回结果,示例代码如下:
using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; static class Program { // 异步Main入口,C# 7.1及以上版本默认支持 static async Task Main() { List<dynamic> resultList = new List<dynamic>(); List<Task<dynamic>> taskList = new List<Task<dynamic>>(); // HttpClient全局复用即可,不要每次请求新建实例 HttpClient httpClient = new HttpClient(); for (int i = 0; i <= 50; i++) { // 直接添加异步任务到任务列表,无需额外用StartNew/Run包装 taskList.Add(SavePageDataAsync($"www.someJsonlink.com?page={i}", httpClient)); } // 等待所有并行任务执行完成,直接获取所有返回值集合 var allResults = await Task.WhenAll(taskList); resultList.AddRange(allResults); // 后续对resultList的业务处理逻辑 } static async Task<dynamic> SavePageDataAsync(string url, HttpClient httpClient) { string page = await httpClient.GetStringAsync(url); return JsonConvert.DeserializeObject(page); } }
如果开发环境不支持异步Main方法,可改用同步等待写法,该写法仅适用于控制台程序入口场景:
static void Main() { // 前面的任务构造逻辑和上面一致 var allResults = Task.WhenAll(taskList).GetAwaiter().GetResult(); resultList.AddRange(allResults); }
内容的提问来源于stack exchange,提问作者Mahdi_J
相关产品推荐
相关产品推荐

