编辑
2025-09-22
C#
00

目录

应用场景
示例 1:并行循环
串行实现
并行实现
示例 2:并行执行多个任务
串行执行
并行执行
示例 3:结合 ValueTask 使用并行
总结

在 .NET 应用程序中,提高执行效率和响应速度是开发者追求的目标之一。随着多核处理器的普及,利用并行编程来充分利用多核处理器的能力成为了提高应用程序性能的有效手段。System.Threading.Tasks.Parallel 类提供了一种简单而强大的并行编程模型,使得开发者能够更加方便地实现并行操作。

本文将介绍 Parallel 类的基本用法,并通过几个实例展示如何在 .NET 应用中使用 Parallel 来提升性能。

应用场景

Parallel 类适用于以下几种场景:

  • 数据并行处理:当需要对数据集合中的每个元素执行相同的操作时,可以使用数据并行来加速处理过程。
  • 并行任务执行:当有多个相互独立的任务需要执行时,可以并行地执行这些任务以减少总体执行时间。

示例 1:并行循环

假设我们需要对一个整数数组的每个元素执行计算密集型操作。

串行实现

C#
int[] numbers = Enumerable.Range(1, 1000000).ToArray(); // 串行处理 var watch = Stopwatch.StartNew(); foreach (var num in numbers) { // 执行某些计算密集型操作 Compute(num); } watch.Stop(); Console.WriteLine($"串行执行时间: {watch.ElapsedMilliseconds} ms");

并行实现

C#
watch.Restart(); Parallel.ForEach(numbers, num => { // 执行相同的计算密集型操作 Compute(num); }); watch.Stop(); Console.WriteLine($"并行执行时间: {watch.ElapsedMilliseconds} ms");

在这个例子中,Compute 方法代表对每个元素执行的操作。通过比较串行和并行处理的执行时间,我们可以看到并行处理通常能显著减少总体执行时间。

示例 2:并行执行多个任务

考虑一个场景,我们需要执行几个相互独立的耗时任务。

串行执行

C#
watch.Restart(); Task task1 = Task.Run(() => LongRunningOperation("Task 1")); Task task2 = Task.Run(() => LongRunningOperation("Task 2")); Task task3 = Task.Run(() => LongRunningOperation("Task 3")); task1.Wait(); task2.Wait(); task3.Wait(); watch.Stop(); Console.WriteLine($"串行任务执行时间: {watch.ElapsedMilliseconds} ms");

并行执行

C#
watch.Restart(); Parallel.Invoke( () => LongRunningOperation("Task 1"), () => LongRunningOperation("Task 2"), () => LongRunningOperation("Task 3") ); watch.Stop(); Console.WriteLine($"并行任务执行时间: {watch.ElapsedMilliseconds} ms");

在这个例子中,LongRunningOperation 方法代表一个耗时的任务。通过并行执行,我们可以在更短的时间内完成所有任务。

示例 3:结合 ValueTask 使用并行

ValueTask 类型是 Task 的一个轻量级替代品,适用于高性能场景。我们可以在并行处理中使用 ValueTask 来进一步优化性能。

C#
static async Task Main(string[] args) { int[] numbers = Enumerable.Range(1, 10).ToArray(); // 创建一个包含数字1到10的数组 await ProcessNumbersAsync(numbers); // 异步处理这些数字 } public static async ValueTask<int> ComputeAsync(int num) { // 模拟异步计算操作 await Task.Delay(10); // 假设这是一个异步操作 return num * num; // 返回数字的平方 } public static async Task ProcessNumbersAsync(int[] numbers) { // 使用LINQ的Select方法将每个数字映射为一个ComputeAsync调用,并立即通过调用.AsTask()将每个ValueTask<int>转换为Task<int> var tasks = numbers.Select(num => ComputeAsync(num).AsTask()).ToArray(); // 现在我们有了Task<int>[],可以安全地使用Task.WhenAll等待所有任务完成 var results = await Task.WhenAll(tasks); // 处理结果 foreach (var result in results) { Console.WriteLine(result); // 打印每个数字的平方 } }

image.png

在这个例子中,我们使用 ValueTask<int> 来表示异步计算的结果。通过 Task.WhenAll 方法,我们可以并行地执行这些异步操作,并等待所有操作完成。

总结

通过使用 .NET 的 Parallel 类,我们可以轻松地实现并行编程,从而显著提高应用程序的执行效率。无论是处理大量数据,还是同时执行多个独立任务,Parallel 都能提供简单而强大的并行解决方案。结合 ValueTask 的使用,可以进一步优化性能,特别是在高性能场景下。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!