c# ForEachAsync 的用法和 Parallel.ForEach 的区别

小宇大大_8591

小宇大大_8591

2026-01-10

811人浏览

原创

ForEachAsync 不是 .NET 原生 API,不存在于 System.Collections.Generic 或 System.Linq 中,而是开发者自定义或第三方库提供的异步遍历方法,基于 Task.WhenAll 实现并发执行,需注意限流与异常聚合;Parallel.ForEach 是 .NET 内置同步并行工具,不支持直接 await 异步操作。

c# foreachasync 的用法和 parallel.foreach 的区别

ForEachAsync 不是 .NET 原生 API

直接说结论:ForEachAsync 不存在于 System.Collections.Generic 或 System.Linq 中。它常被误认为是 List 的扩展方法,实际是开发者自己写的异步遍历辅助方法,或来自第三方库(如 Microsoft.VisualStudio.Threading 或社区 NuGet 包)。Parallel.ForEach 则是 .NET Framework 4+ 内置的并行同步执行工具,位于 System.Threading.Tasks 命名空间。

ForEachAsync 通常怎么实现和使用

常见自定义 ForEachAsync 是基于 Task.WhenAll 的并发控制,不是串行 await 每一项(那叫 foreach + await),而是批量触发所有异步操作再统一等待:

public static async Task ForEachAsync<t>(this IEnumerable<t> source, Func<t task> body)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (body == null) throw new ArgumentNullException(nameof(body));

    var tasks = source.Select(item => body(item));
    await Task.WhenAll(tasks);
}</t></t></t>

使用时注意:

  • ForEachAsync 默认不控制并发数,1000 个元素就并发 1000 个 Task,可能压垮服务或耗尽连接池
  • 若需限流,得改用 SemaphoreSlim 包裹 body,或借助 System.Threading.Tasks.Dataflow 的 ActionBlock
  • 异常行为:任意一个 Task 抛出异常,Task.WhenAll 就会以 AggregateException 形式抛出,所有异常都会被捕获(不像串行 foreach + await 遇到第一个异常就停)

Parallel.ForEach 是同步阻塞式并行,不能直接 await 异步操作

Parallel.ForEach 在每个线程上执行的是同步委托 Action,传入 async lambda 会导致“火把式异步”(fire-and-forget)——编译能过,但实际只启动了 Task 并立即返回,Parallel 不等它完成就继续下一项,最终结果不可控:

Parallel.ForEach(items, item =>
{
    SomeAsyncOperation(item).Wait(); // ❌ 不推荐:阻塞线程,易死锁、拖慢吞吐
});

正确做法只有两个:

Oc Gateway Guardian
Oc Gateway Guardian

通过预检、监控诊断和证据捕获,防止长时间运行的 OpenClaw 网关不安全重启。

下载
  • 坚持同步逻辑:所有操作必须是 CPU-bound 或已同步封装(如 File.ReadAllBytes)
  • 改用异步方案:放弃 Parallel.ForEach,回到 ForEachAsync(自定义或第三方)或 Task.WhenAll + Select

性能差异明显:Parallel.ForEach 适合密集计算;ForEachAsync 适合 I/O 密集(HTTP 请求、DB 查询),但必须小心资源竞争与并发上限。

别混淆 Task.Run + ForEachAsync 和 Parallel.ForEach

有人试图用 Task.Run(() => Parallel.ForEach(...)) 把同步并行“包一层”变成异步,这是典型误解:

  • 没解决根本问题:内部仍是同步执行,只是挪到了后台线程池线程上
  • 额外增加调度开销,且无法取消、难以监控进度
  • 如果 Parallel.ForEach 里混了 await,一样会掉进“未等待异步任务”的陷阱

真正需要异步并行时,优先选明确支持 Func 的抽象(如 AsyncEnumerable 的 ForEachAwaitAsync,.NET 6+ 的 IAsyncEnumerable.ForEachAwaitAsync 扩展),或者自己加信号量限流的 ForEachAsync 实现。

最易被忽略的一点:异步并发数 ≠ 线程数,而 Parallel.ForEach 的度量单位是线程。IO 操作不占线程,但可能占 socket、数据库连接、API 配额——这些才是 ForEachAsync 真正要管的资源。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

microsoft 异步任务 c# gate

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

2025.12.04

858

13

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.15

1171

5

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

2025.11.08

345

7

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

2026.01.05

674

7

C++ Lambda 表达式与函数式编程
C++ Lambda 表达式与函数式编程

深入讲解 C++ Lambda 表达式与函数式编程范式,涵盖 Lambda 基础语法与返回值推导、值捕获与引用捕获的区别与陷阱、初始化捕获(C++14 广义捕获)、泛型 Lambda(auto 参数)、mutable 关键字修改捕获变量、std::function 类型擦除与函数包装、std::bind 参数绑定(及其被 Lambda 替代的趋势)、Lambda 在 STL 算法(sort/transform/for_each/remo

2026.05.06

869

22

Java 函数式接口与 Lambda 进阶技巧
Java 函数式接口与 Lambda 进阶技巧

在 Java Stream 基础之上进一步深入函数式编程,涵盖 @FunctionalInterface 注解与自定义函数式接口设计、四种方法引用(静态/实例/对象/构造器)的使用场景、Lambda 中的 effectively final 变量捕获规则、函数组合(andThen/compose)与柯里化技巧、Comparator 链式比较器构建、CompletableFuture 异步函数式编排、Reactor / RxJava 响应

2026.05.08

468

28

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

4898

6

vscode和visualstudio的区别
vscode和visualstudio的区别

Visual Studio是一款功能强大的集成开发环境(IDE),适用于专业开发人员进行复杂项目的构建。而VSCode则是一款轻量级的代码编辑器,更适合各种规模的项目开发。想了解更多vscode的相关内容,可以阅读本专题下面的文章。

2024.03.15

1156

8

vscode和visualstudio对比分析
vscode和visualstudio对比分析

VSCode是一款轻量级代码编辑器,界面简洁,支持广泛的编程语言,适合个人开发者和小团队。而Visual Studio是一款全功能IDE,界面复杂但功能丰富,适合大型项目开发和团队协作,特别是面向.NET开发。想了解更多vscode的相关内容,可以阅读本专题下面的文章。

2024.04.01

2092

10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go-Zero goctl安装与使用手册
Go-Zero goctl安装与使用手册

共0课时 | 0人学习

DBeaver生态工具dbvr官方手册
DBeaver生态工具dbvr官方手册

共0课时 | 0人学习