Parallel.ForEach异步处理丢数据+createExcel执行顺序异常问题求助
问题修复方案
问题2:createExcel()提前执行的修复
原代码里用task2.Wait()是错误的异步等待方式,在async方法中必须用await来保证任务完成后再执行后续逻辑。修改DoworkAsync方法:
private async Task DoworkAsync(List<OrderFragment> of) { var sw = Stopwatch.StartNew(); // 直接await每个任务,确保顺序执行且等待完成 var orderJson = await CreateOrderjson(of); var bearerToken = await GetBearerToken(); await SubmitOrderIntake(orderJson, bearerToken); await createExcel(); }
这样createExcel()只会在SubmitOrderIntake完全执行完毕后才启动。
问题1:响应结果缺失的修复
核心问题是Parallel.ForEach不支持异步委托——它会启动异步任务但不会等待任务完成,导致SubmitOrderIntake提前返回,部分PostOrderintake的结果还没被收集。改用Task.WhenAll等待所有异步请求完成,同时正确收集结果:
修改SubmitOrderIntake方法
private async Task<string[]> SubmitOrderIntake(List<string> orderJson, string bearerToken) { // 为每个order创建异步请求任务 var postTasks = orderJson.Select(order => PostOrderintake(order, bearerToken)); // 等待所有请求完成,获取全部结果 var allPostResults = await Task.WhenAll(postTasks); // 合并所有ConcurrentBag中的结果为数组返回 return allPostResults.SelectMany(bag => bag).ToArray(); }
关键说明
Parallel.ForEach搭配async lambda会导致“火与遗忘”,任务未执行完方法就返回,这是结果缺失的根本原因。Task.WhenAll会等待所有异步任务完成后再继续,确保能收集到所有响应结果。- 保留
ConcurrentBag<string>作为PostOrderintake的返回类型是合理的,它是线程安全集合,适合多线程环境下添加数据。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

