0

0

c# ForAll 和 ForEach 在PLINQ中的区别

月夜之吻

月夜之吻

发布时间:2026-01-03 02:37:28

|

348人浏览过

|

来源于php中文网

原创

forall是plinq专属的无返回、不保序、不合并结果的并行消费方法,仅用于parallelquery末端;foreach是ienumerable/list的顺序遍历方法,parallelquery上不存在该方法。

c# forall 和 foreach 在plinq中的区别

ForAll 是 PLINQ 专属的并行消费方法,ForEach 是普通集合的顺序遍历

ForAll 只存在于 ParallelQuery<t></t>(即调用 AsParallel() 后的查询结果),它不返回值、不保证执行顺序、也不合并结果——每个线程拿到自己的数据块后立刻执行委托,完事就退出。ForEach 则是 IEnumerable<t></t>List<t></t> 上的实例方法,纯顺序执行,线程安全需自行保障,且会等全部元素处理完才返回。

  • ForAll 不能链式返回新集合,只适合“发通知”“写日志”“更新非共享状态”这类无返回、无依赖的操作
  • ForEach 在 PLINQ 中根本不存在——你写 list.AsParallel().ForEach(...) 会编译失败,因为 ParallelQuery<t></t> 没有这个方法;真正能用的是 Parallel.ForEach(...)(来自 System.Threading.Tasks.Parallel),但那是另一套 API,和 LINQ 风格无关
  • 别把 Parallel.ForEachParallelQuery.ForAll 混为一谈:前者接受 IEnumerable 或分区器,后者只接受 ParallelQuery

为什么 ForAll 不保证顺序?这和 PLINQ 的分区机制直接相关

PLINQ 把源集合切分成若干段(partition),分给不同线程处理。这些段大小不固定、分配时机不确定、完成时间也不同。ForAll 就是让每个线程在自己分到的那块数据上“立刻开干”,不做任何等待或排序协调——所以输出顺序完全不可预测。

  • 如果你需要顺序输出(比如写入文件、生成有序报告),ForAll 不适用;该用 foreach 遍历 ToArray()ToList() 结果
  • ForAll 内部跳过结果合并步骤,因此比 ToArray() + foreach 快,尤其在数据量大、操作耗时长时优势明显
  • 若委托里访问了共享变量(如静态计数器、全局 list),必须加锁或改用线程安全类型(如 ConcurrentBag<t></t>),否则结果错乱

常见误用:想并行又想要顺序,结果既慢又错

典型错误是这样写:

FormX
FormX

AI自动从表格和文档中提取数据

下载
numbers.AsParallel()
    .Where(n => IsPrime(n))
    .OrderBy(n => n) // 强制全缓冲 + 排序合并
    .ForAll(Console.WriteLine); // 以为能按序打印素数

问题在于:OrderBy 会让 PLINQ 缓冲所有结果再排序,彻底抵消并行优势;而 ForAll 仍不保证输出顺序(即使输入已排序,多线程并发写控制台也会乱序)。

  • 要顺序输出:去掉 ForAll,改用 foreach (var x in query.OrderBy(...)) Console.WriteLine(x);
  • 要纯并行处理 + 丢弃结果:保留 ForAll,但删掉 OrderBy 等强制合并的运算符
  • 想边算边处理?PLINQ 默认“部分缓冲”,可用 WithMergeOptions(ParallelMergeOptions.NotBuffered) 让结果更早流出,但仍不保序

ForEach 方法名重复导致的认知陷阱

名字都叫 ForEach,但实际是三个不同东西:

  • List<t>.ForEach()</t>:实例方法,顺序,单线程,属于 .NET Framework 2.0 就有的老 API
  • Parallel.ForEach():静态方法,接受 IEnumerable 或自定义分区器,可配置并行度、取消令牌等,属于 TPL
  • ParallelQuery<t>.ForAll()</t>:扩展方法,仅用于 PLINQ 查询链末端,无返回、无合并、不保序

它们之间没有继承或重载关系,只是命名巧合。选哪个,取决于你手头的数据类型和目标:是已有集合想并行遍历?用 Parallel.ForEach;是 LINQ 查询想加速过滤+消费?用 AsParallel().Where(...).ForAll(...);只是简单循环打印?foreach 最稳。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

333

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

223

2025.10.31

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

138

2026.02.12

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1561

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

241

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

128

2025.10.17

php中foreach用法
php中foreach用法

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

202

2025.12.04

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

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

723

2023.08.10

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

4

2026.03.04

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

光速学会docker容器
光速学会docker容器

共33课时 | 2万人学习

时间管理,自律给我自由
时间管理,自律给我自由

共5课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号