在现代软件开发中,随着多核处理器的普及,并行编程变得越来越重要。C# 提供了多种方式来实现并行编程,以提高应用程序的性能和响应速度。本文将详细介绍如何在 C# 中实现并行编程,包括使用 Task
、Parallel
类、PLINQ
以及 async/await
等机制。
并行编程是指在同一时间内执行多个任务,以充分利用多核处理器的计算能力。与传统的串行编程相比,并行编程可以显著提高程序的执行效率,尤其是在处理大量数据或执行复杂计算时。
在 C# 中,并行编程主要通过以下几种方式实现:
Task
和 Parallel
类,用于创建和管理并行任务。Task
类是 C# 中用于表示异步操作的基本单元。通过 Task
,可以轻松地创建和管理并行任务。
using System; using System.Threading.Tasks; class Program { static void Main(string[] args) { Task task1 = Task.Run(() => DoWork("Task 1")); Task task2 = Task.Run(() => DoWork("Task 2")); Task.WaitAll(task1, task2); Console.WriteLine("All tasks completed."); } static void DoWork(string taskName) { Console.WriteLine($"{taskName} is running on thread {Task.CurrentId}"); Task.Delay(1000).Wait(); // 模拟耗时操作 Console.WriteLine($"{taskName} completed."); } }
在上面的代码中,我们使用 Task.Run
方法创建了两个并行任务 task1
和 task2
,并通过 Task.WaitAll
方法等待它们完成。
Task
还可以返回一个值,通过 Task<TResult>
类型来表示。
using System; using System.Threading.Tasks; class Program { static void Main(string[] args) { Task<int> task1 = Task.Run(() => CalculateSum(1, 10)); Task<int> task2 = Task.Run(() => CalculateSum(11, 20)); int result1 = task1.Result; int result2 = task2.Result; Console.WriteLine($"Sum of 1-10: {result1}"); Console.WriteLine($"Sum of 11-20: {result2}"); } static int CalculateSum(int start, int end) { int sum = 0; for (int i = start; i <= end; i++) { sum += i; } return sum; } }
在这个例子中,task1
和 task2
分别计算了 1 到 10 和 11 到 20 的和,并通过 Result
属性获取了计算结果。
Parallel
类提供了简单的并行循环和并行任务执行的方法,适用于需要对集合进行并行处理的场景。
Parallel.For
方法可以并行地执行一个循环。
using System; using System.Threading.Tasks; class Program { static void Main(string[] args) { Parallel.For(0, 10, i => { Console.WriteLine($"Task {i} is running on thread {Task.CurrentId}"); Task.Delay(1000).Wait(); // 模拟耗时操作 Console.WriteLine($"Task {i} completed."); }); Console.WriteLine("All tasks completed."); } }
在这个例子中,Parallel.For
并行地执行了 10 个任务,每个任务都会打印当前任务的编号和线程 ID。
Parallel.ForEach
方法可以并行地遍历一个集合。
using System; using System.Collections.Generic; using System.Threading.Tasks; class Program { static void Main(string[] args) { List<string> items = new List<string> { "Item1", "Item2", "Item3", "Item4", "Item5" }; Parallel.ForEach(items, item => { Console.WriteLine($"Processing {item} on thread {Task.CurrentId}"); Task.Delay(1000).Wait(); // 模拟耗时操作 Console.WriteLine($"Completed processing {item}."); }); Console.WriteLine("All items processed."); } }
在这个例子中,Parallel.ForEach
并行地处理了 items
列表中的每个元素。
PLINQ (Parallel LINQ) 是 LINQ 的并行版本,允许对集合进行并行查询。
AsParallel
方法可以将 LINQ 查询转换为并行查询。
using System; using System.Linq; class Program { static void Main(string[] args) { var numbers = Enumerable.Range(1, 100); var evenNumbers = numbers.AsParallel() .Where(n => n % 2 == 0) .OrderBy(n => n) .ToList(); Console.WriteLine("Even numbers:"); foreach (var number in evenNumbers) { Console.WriteLine(number); } } }
在这个例子中,AsParallel
方法将 numbers
集合的查询转换为并行查询,从而加速了查询过程。
WithDegreeOfParallelism
方法可以指定并行查询的最大并行度。
using System; using System.Linq; class Program { static void Main(string[] args) { var numbers = Enumerable.Range(1, 100); var evenNumbers = numbers.AsParallel() .WithDegreeOfParallelism(4) .Where(n => n % 2 == 0) .OrderBy(n => n) .ToList(); Console.WriteLine("Even numbers:"); foreach (var number in evenNumbers) { Console.WriteLine(number); } } }
在这个例子中,WithDegreeOfParallelism(4)
指定了并行查询的最大并行度为 4。
async/await
是 C# 中用于编写异步代码的关键字,可以避免阻塞主线程,提高应用程序的响应速度。
using System; using System.Threading.Tasks; class Program { static async Task Main(string[] args) { Console.WriteLine("Starting async tasks..."); Task task1 = DoWorkAsync("Task 1"); Task task2 = DoWorkAsync("Task 2"); await Task.WhenAll(task1, task2); Console.WriteLine("All async tasks completed."); } static async Task DoWorkAsync(string taskName) { Console.WriteLine($"{taskName} is running on thread {Task.CurrentId}"); await Task.Delay(1000); // 模拟耗时操作 Console.WriteLine($"{taskName} completed."); } }
在这个例子中,DoWorkAsync
方法是一个异步方法,使用 await
关键字等待耗时操作完成。Main
方法使用 await Task.WhenAll
等待所有异步任务完成。
异步方法也可以返回一个值。
using System; using System.Threading.Tasks; class Program { static async Task Main(string[] args) { Console.WriteLine("Starting async tasks..."); Task<int> task1 = CalculateSumAsync(1, 10); Task<int> task2 = CalculateSumAsync(11, 20); int result1 = await task1; int result2 = await task2; Console.WriteLine($"Sum of 1-10: {result1}"); Console.WriteLine($"Sum of 11-20: {result2}"); } static async Task<int> CalculateSumAsync(int start, int end) { int sum = 0; for (int i = start; i <= end; i++) { sum += i; await Task.Delay(100); // 模拟耗时操作 } return sum; } }
在这个例子中,CalculateSumAsync
方法是一个异步方法,返回一个 int
类型的值。Main
方法使用 await
关键字获取异步方法的返回值。
C# 提供了多种方式来实现并行编程,包括 Task
、Parallel
类、PLINQ
以及 async/await
等机制。通过合理地使用这些工具,可以显著提高应用程序的性能和响应速度。在实际开发中,应根据具体需求选择合适的并行编程方式,并注意避免常见的并发问题,如死锁和竞态条件。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。