除了用于 I/O 的 async/await,.NET 提供了 用于 — 在多个核心上运行计算。关键区别:/ 用于 I/O 并发(非阻塞等待),而 、 和 PLINQ 用于并行化 CPU 密集型工作。
asyncawaitTask.RunParallelasync/await → I/O-bound concurrency. Frees the thread during waits (DB, network).
Does NOT add CPU parallelism.
Parallelism → CPU-bound work spread across MULTIPLE CORES (computation, processing).
Use Task.Run, Parallel.For/ForEach, PLINQ.
// run a CPU-intensive computation on a thread pool thread (don't block the caller)
int result = await Task.Run(() => ExpensiveComputation());
// run multiple in parallel and combine
var tasks = items.Select(item => Task.Run(() => Process(item)));
var results = await Task.WhenAll(tasks); // wait for all
Task.Run 在线程池线程上调度工作 — 用它来并行化 CPU-bound 计算(不用于 I/O,async/await 已足够不需额外线程)。
// Parallel.For/ForEach — process a collection across cores
Parallel.ForEach(items, item => Process(item)); // automatically uses multiple cores
Parallel.For(0, 1000, i => Compute(i));
// PLINQ — parallel LINQ
var results = data.AsParallel().Where(x => IsValid(x)).Select(Transform).ToList();
Parallel.For/ForEach 和 PLINQ(.AsParallel())自动跨核心分配工作 — 非常适合对独立项进行 CPU-heavy 处理。(仅对真正 CPU-bound、大规模工作才值得 — 有开销。)
// parallel code accessing SHARED state needs synchronization or thread-safe types
lock (_lock) { _counter++; } // lock for mutual exclusion
Interlocked.Increment(ref _counter); // lock-free atomic
var dict = new ConcurrentDictionary<string, int>(); // thread-safe collection
理解 async/await 之外的 Tasks 和 parallelism 是构建高性能 C# 应用程序的重要高级知识,I/O 并发和 CPU 并行之间的关键区别是核心洞察 — 这是常见的混淆点。async/await 处理 I/O-bound 并发(在等待期间释放线程),但不提供 CPU 并行,而 CPU-bound 工作(计算、数据处理)受益于通过 Task.Run(将 CPU 工作卸载到线程池线程)、Parallel.For/ForEach 和 PLINQ(.AsParallel())在核心间的实际并行化。
了解哪个工具适合 — 用于 I/O 的 async/await,用于 CPU-bound 工作的 TPL 并行工具 — 对于有效的性能优化至关重要,因为使用错误的工具(例如期望 async 加速计算,或为 async 已高效处理的 I/O 启动线程)是无效的。
同样重要的是理解线程安全:并行代码访问共享状态需要同步(lock、Interlocked 用于原子操作,或线程安全集合如 ConcurrentDictionary)以避免竞争条件 — 这是并行代码中的关键正确性问题。
理解 I/O-vs-CPU 区别、并行工具(Task.Run、Parallel、PLINQ)和线程安全要求对于编写正确、高性能的并发和并行 C# 代码是有价值的。
由于现代应用程序通常需要 I/O 并发和 CPU 并行,以及选择正确的方法和正确处理线程安全是使并行代码有效和正确的关键,这对于性能敏感的 C# 开发来说是重要的、经常相关的高级知识。