大家好,又见面了,我是你们的朋友全栈君。
如何:编写简单的 Parallel.ForEach 循环
本文档使用 lambda 表达式在 PLINQ 中定义委托。 如果不熟悉 C# 或 Visual Basic 中的 lambda 表达式,请参阅 PLINQ 和 TPL 中的 Lambda 表达式。
示例
此示例假定 C:UsersPublicPicturesSample Pictures 文件夹中有几个 .jpg 文件,并创建名为“Modified”的新子文件夹。 运行该示例时,它会旋转示例图片中的每个 .jpg 图像并将其保存到“Modified”文件夹 可以根据需要修改这两个路径。
C#复制
代码语言:javascript复制using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace ParallelExample
{
class Program
{
static void Main()
{
// 2 million
var limit = 2_000_000;
var numbers = Enumerable.Range(0, limit).ToList();
var watch = Stopwatch.StartNew();
var primeNumbersFromForeach = GetPrimeList(numbers);
watch.Stop();
var watchForParallel = Stopwatch.StartNew();
var primeNumbersFromParallelForeach = GetPrimeListWithParallel(numbers);
watchForParallel.Stop();
Console.WriteLine($"Classical foreach loop | Total prime numbers : {primeNumbersFromForeach.Count} | Time Taken : {watch.ElapsedMilliseconds} ms.");
Console.WriteLine($"Parallel.ForEach loop | Total prime numbers : {primeNumbersFromParallelForeach.Count} | Time Taken : {watchForParallel.ElapsedMilliseconds} ms.");
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
/// <summary>
/// GetPrimeList returns Prime numbers by using sequential ForEach
/// </summary>
/// <param name="inputs"></param>
/// <returns></returns>
private static IList<int> GetPrimeList(IList<int> numbers) => numbers.Where(IsPrime).ToList();
/// <summary>
/// GetPrimeListWithParallel returns Prime numbers by using Parallel.ForEach
/// </summary>
/// <param name="numbers"></param>
/// <returns></returns>
private static IList<int> GetPrimeListWithParallel(IList<int> numbers)
{
var primeNumbers = new ConcurrentBag<int>();
Parallel.ForEach(numbers, number =>
{
if (IsPrime(number))
{
primeNumbers.Add(number);
}
});
return primeNumbers.ToList();
}
/// <summary>
/// IsPrime returns true if number is Prime, else false.(https://en.wikipedia.org/wiki/Prime_number)
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
private static bool IsPrime(int number)
{
if (number < 2)
{
return false;
}
for (var divisor = 2; divisor <= Math.Sqrt(number); divisor )
{
if (number % divisor == 0)
{
return false;
}
}
return true;
}
}
}
Parallel.ForEach 循环的工作原理类似 Parallel.For 循环。 该循环对源集合进行分区,并根据系统环境在多个线程上安排工作。 系统上的处理器越多,并行方法的运行速度就越快。 对于一些源集合,有序循环可能会更快,具体视源大小以及该循环要执行的工作类型而定。 有关性能的详细信息,请参阅数据和任务并行的潜在问题。
若要详细了解并行循环,请参阅如何:编写简单的 Parallel.For 循环。
若要将 Parallel.ForEach 与非泛型集合结合使用,可以使用 Enumerable.Cast 扩展方法,将集合转换为泛型集合,如下面的示例所示:
C#复制
代码语言:javascript复制Parallel.ForEach(nonGenericCollection.Cast<object>(),
currentElement =>
{
});
还可以使用并行 LINQ (PLINQ) 并行处理 并行 LINQ (PLINQ)。
编译并运行代码
可以作为 .NET Framework 的控制台应用程序或 .NET Core 的控制台应用程序编译代码。
Visual Studio 中有适用于 Windows 桌面和 .NET Core 的 Visual Basic 和 C# 控制台应用程序模板。
从命令行,可使用 .NET Core CLI 命令(例如 dotnet new console
或 dotnet new console -lang vb
),或者可创建文件并使用 .NET Framework 应用程序提供的命令行编译器。
对于.NET Core 项目,必须引用 System.Drawing.Common NuGet 包。 在 Visual Studio 中,使用 NuGet 包管理器安装该包。 或者,也可以在 *.csproj 或 *.vbproj 文件中添加对包的引用:
XML复制
代码语言:javascript复制<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="4.5.1" />
</ItemGroup>
要从命令行运行 .NET Core 控制台应用程序,请使用包含该应用程序的文件夹中的 dotnet run
。
要从 Visual Studio 中运行控制台应用程序,请按 F5。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/161801.html原文链接:https://javaforall.cn