编辑
2025-10-10
C#
00

目录

什么是任务并行库(TPL)
使用 Parallel 类处理大量数据
示例:使用 Parallel.ForEach 并行处理大量数据
使用 Task 并行执行自定义任务
示例:并行下载多个文件
使用 PLINQ 并行查询
示例:使用 PLINQ 进行数据过滤和处理
注意线程安全和数据一致性
示例:使用线程安全的集合
结论

随着数据量的不断增长,高效地处理大量数据已成为开发者必须面对的挑战。C# 中的任务并行库(Task Parallel Library,简称 TPL)提供了简便且强大的方式来实现并行编程,充分利用多核处理器的优势,加速数据处理。本篇文章将详细介绍如何使用 TPL 处理大量数据,并提供完整的示例代码。

什么是任务并行库(TPL)

TPL 是 .NET Framework 提供的用于实现并行编程的库,位于 System.Threading.Tasks 命名空间下。它简化了多线程编程,帮助开发者更容易地创建、等待和管理任务。

使用 Parallel 类处理大量数据

Parallel 类提供了并行执行循环的功能,如 Parallel.ForParallel.ForEach,可用于并行处理集合中的数据。

示例:使用 Parallel.ForEach 并行处理大量数据

假设我们有一个包含大量整数的列表,需要对每个整数进行计算处理。

下面是完整的代码示例:

C#
using System.Collections.Generic; namespace AppTPL { internal class Program { static void Main(string[] args) { List<int> numbers = GenerateLargeData(1000000); ProcessData(numbers); } static List<int> GenerateLargeData(int count) { List<int> data = new List<int>(count); for (int i = 0; i < count; i++) { data.Add(i); } return data; } static void ProcessData(List<int> data) { Parallel.ForEach(data, number => { // 模拟计算密集型任务 double result = Math.Pow(number, 2); // 处理结果(此处省略) Console.WriteLine(result); }); } } }

image.png

以上代码中,Parallel.ForEach 方法将列表中的数据分配到多个线程中并行处理,从而加速处理过程。

使用 Task 并行执行自定义任务

除了并行处理循环,TPL 还允许创建和管理自定义任务,可用于更复杂的并行操作。

示例:并行下载多个文件

假设我们需要从多个 URL 下载文件,我们可以使用 Task 来并行执行下载操作。

下面是完整的代码示例:

C#
using System; using System.Collections.Generic; namespace AppTPL { internal class Program { static async Task Main(string[] args) { List<string> urls = new List<string> { "https://images.pexels.com/photos/16471876/pexels-photo-16471876.jpeg?cs=srgb&dl=pexels-helloaesthe-16471876.jpg&fm=jpg&_gl=1*1vqwmcp*_ga*OTYxNjI2MTc3LjE3Mjk0Nzc4NDM.*_ga_8JE65Q40S6*MTczNDIxNjIxMi4zLjEuMTczNDIxNjIxNS4wLjAuMA..", "https://images.pexels.com/photos/18884059/pexels-photo-18884059.jpeg?cs=srgb&dl=pexels-aljona-ovtsinnikova-121486965-18884059.jpg&fm=jpg&_gl=1*1vqwmcp*_ga*OTYxNjI2MTc3LjE3Mjk0Nzc4NDM.*_ga_8JE65Q40S6*MTczNDIxNjIxMi4zLjEuMTczNDIxNjIxNS4wLjAuMA..", }; await DownloadFilesAsync(urls); } static async Task DownloadFilesAsync(List<string> urls) { List<Task> downloadTasks = new List<Task>(); foreach (var url in urls) { downloadTasks.Add(Task.Run(async () => { using HttpClient client = new HttpClient(); var data = await client.GetByteArrayAsync(url); File.WriteAllBytes(new Random().Next(1, 1000000) + ".jpg", data); // 保存数据(此处省略) })); } await Task.WhenAll(downloadTasks); } } }

在此示例中,我们为每个下载操作创建一个任务,并使用 Task.WhenAll 方法等待所有下载任务完成。

使用 PLINQ 并行查询

并行 LINQ(PLINQ)提供了并行化 LINQ 查询的能力,可以对数据集合进行并行查询和处理。

示例:使用 PLINQ 进行数据过滤和处理

下面是完整的代码示例:

C#
using System; using System.Collections.Generic; namespace AppTPL { internal class Program { static void Main(string[] args) { List<int> numbers = GenerateLargeData(1000); ProcessDataWithPLINQ(numbers); } static List<int> GenerateLargeData(int count) { List<int> data = new List<int>(count); for (int i = 0; i < count; i++) { data.Add(i); } return data; } static void ProcessDataWithPLINQ(List<int> data) { var results = data.AsParallel() .Where(number => number % 2 == 0) .Select(number => Math.Sqrt(number)) .ToList(); Console.WriteLine("Results: " + string.Join(", ", results)); } } }

image.png

使用 AsParallel() 方法将集合转换为并行查询,后续的查询操作将自动并行执行。

注意线程安全和数据一致性

在并行处理中,需注意线程安全问题。如需要修改共享数据,应使用线程安全的数据结构或使用锁。

示例:使用线程安全的集合

下面是完整的代码示例:

C#
using System; using System.Collections.Concurrent; using System.Collections.Generic; namespace AppTPL { internal class Program { static List<int> GenerateLargeData(int count) { List<int> data = new List<int>(count); for (int i = 0; i < count; i++) { data.Add(i); } return data; } static void Main(string[] args) { List<int> numbers = GenerateLargeData(1000000); ProcessDataSafely(numbers); } static void ProcessDataSafely(List<int> data) { ConcurrentBag<double> results = new ConcurrentBag<double>(); Parallel.ForEach(data, number => { double result = Math.Pow(number, 2); results.Add(result); }); // 结果已安全地添加到线程安全的集合中 } } }

ConcurrentBag 是一个线程安全的集合,允许多个线程同时添加和读取数据。

结论

任务并行库(TPL)为 C# 开发者提供了强大的并行处理能力,能够有效地处理大量数据。通过 Parallel 类、Task 和 PLINQ,可以根据不同的需求选择合适的并行处理方式。在实际应用中,需要注意线程安全和资源管理,以确保程序的正确性和高效性。

本文作者:技术老小子

本文链接:

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