You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断Parallel.ForEach执行完毕以执行后续指令?

问题解决:等待异步并行操作完成后再记录日志

你的核心问题是**Parallel.ForEach不支持异步委托**,传入的async Entry => ...属于async void类型的方法,Parallel.ForEach只会启动这些异步任务,但不会等待它们执行完毕,所以日志会直接跳过循环提前输出。哪怕用Task.Run包裹,也只是等Parallel.ForEach的循环启动完所有任务,不会等异步操作结束。

正确解决方案

方案1:使用Task.WhenAll(兼容所有.NET版本)

把每个元素的异步操作转换成Task集合,再用Task.WhenAll等待所有任务完成:

// 生成所有异步任务
var tasks = grpfiles.Select(entry => Process(entry.ToList()));
// 等待所有任务执行完毕
await Task.WhenAll(tasks);
// 此时所有异步操作都已完成,再记录日志
_logger.LogInformation($"End function at: {DateTime.Now}");

方案2:使用Parallel.ForEachAsync(.NET 6及以上版本推荐)

这是官方为异步并行迭代专门设计的API,能正确跟踪并等待所有异步操作完成:

await Parallel.ForEachAsync(grpfiles, async (entry, cancellationToken) =>
{
    await Process(entry.ToList());
});
_logger.LogInformation($"End function at: {DateTime.Now}");

原写法失效原因

  • Parallel.ForEach是为同步代码设计的,它不识别异步lambda的返回值(Task),会把异步lambda当作async void方法处理。这种方法的异步任务无法被跟踪,Parallel.ForEach执行到lambda里的第一个await时,就会直接开始下一个迭代,不会等待整个异步方法完成。
  • 用Task.Run包裹的写法,只是让主线程等待Parallel.ForEach的循环体执行完毕(也就是所有async void任务都启动了),但这些任务的异步逻辑还在后台运行,所以日志还是会提前输出。

内容的提问来源于stack exchange,提问作者lizarazou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:45:33