PowerShell Foreach-Object -Parallel
最后修改:2025 年 2 月 15 日
本教程涵盖 PowerShell 中的 Foreach-Object -Parallel cmdlet。它支持并行处理管道输入,以提高性能。并行执行可以显著加快处理大型数据集的操作速度。该 cmdlet 是作为 PowerShell Core 的一部分在 PowerShell 7.0 中引入的。
并行处理基础知识
并行处理同时执行多个操作。在 PowerShell 中,这是通过 Foreach-Object -Parallel 实现的。它以并发方式处理管道项,而不是顺序处理。每次迭代都在单独的 PowerShell runspace 中运行。这对于 CPU 密集型或 I/O 密集型操作非常理想。
基本并行处理
最简单的用法是以并行方式处理每个输入项。默认情况下,它使用多达 5 个并行线程。脚本块包含要执行的操作。$_ 变量表示当前管道项。
1..10 | Foreach-Object -Parallel {
"Processing item $_"
Start-Sleep -Milliseconds 500
}
此示例并行处理数字 1 到 10。每次迭代休眠 500 毫秒。由于并行执行,输出顺序可能会有所不同。请注意,与顺序处理相比,项完成得更快。
控制线程数
-ThrottleLimit 参数控制最大并行线程数。较高的值会增加并发性,但会消耗更多资源。较低的值会减少资源使用,但会降低速度。最佳值取决于您的系统和工作负载。
1..20 | Foreach-Object -Parallel {
"Processing item $_ (Thread $PID)"
Start-Sleep -Seconds 1
} -ThrottleLimit 3
此示例将处理限制为 3 个并发线程。$PID 显示每个 runspace 的进程 ID。请注意,只有 3 个项同时处理。根据您的系统能力调整吞吐量限制。
使用外部变量
-Using 范围修饰符可以访问外部变量。默认情况下,并行脚本块具有隔离的范围。这可以防止竞态条件,但需要显式共享。使用 $using:variableName 引用外部变量。
$prefix = "Result"
1..5 | Foreach-Object -Parallel {
"$($using:prefix): $_ squared is $($_ * $_)"
}
此示例使用外部 $prefix 变量。每次迭代都会计算数字的平方。$using: 前缀访问外部变量。输出将前缀与计算结果结合起来。
并行错误处理
错误处理方式与顺序处理类似。Try/Catch 块可以捕获并行过程中的异常。错误会在完成后汇总并报告。使用 -ErrorAction 控制错误行为。
1..5 | Foreach-Object -Parallel {
try {
if ($_ % 2 -eq 0) {
throw "Even number error"
}
"Processed odd $_"
}
catch {
"Error processing $_: $_"
}
}
此示例为偶数引发错误。奇数正常处理,没有错误。每个错误都会被单独捕获和处理。输出清晰地显示了成功和失败的项。
从并行中返回对象
并行块可以将对象返回到管道。输出会被收集并在所有项完成后发出。返回的对象会保留其原始类型。这使得进一步的管道处理成为可能。
$results = 1..10 | Foreach-Object -Parallel {
[PSCustomObject]@{
Number = $_
Square = $_ * $_
IsEven = $_ % 2 -eq 0
}
}
$results | Format-Table
此示例为每个数字返回自定义对象。每个对象包含数字、其平方和奇偶性。结果收集在 $results 变量中。Format-Table 整齐地显示收集的数据。
并行文件处理
并行处理非常适合 I/O 密集型操作。文件操作可以从并行执行中获得巨大的好处。此示例并发处理多个文件。Measure-Command 显示了性能提升。
$files = Get-ChildItem -Path "C:\Temp\*.log"
Measure-Command {
$files | Foreach-Object -Parallel {
$content = Get-Content $_.FullName
"$($_.Name) has $($content.Count) lines"
} -ThrottleLimit 10
}
此示例并行处理所有 .log 文件。每个文件的行数都会被计算并报告。将 ThrottleLimit 增加以更好地利用 I/O。Measure-Command 显示总执行时间。
并行 API 请求
Web 请求非常适合并行处理。每个请求独立于其他请求运行。这大大缩短了总执行时间。使用 Invoke-RestMethod 进行 API 调用。
$urls = @(
"https://api.github.com/users/powershell"
"https://api.github.com/users/microsoft"
"https://api.github.com/users/github"
)
$urls | Foreach-Object -Parallel {
try {
$response = Invoke-RestMethod -Uri $_
"User $($response.login) has $($response.public_repos) repos"
}
catch {
"Failed to fetch $_"
}
}
此示例并行获取 GitHub 用户数据。每个 URL 都被并发处理。结果显示用户名和存储库计数。错误会被捕获并得到妥善处理。
复杂的并行工作流
并行处理可以组合多个操作。此示例展示了一个完整的数据处理工作流。它演示了变量共享和结果聚合。-AsJob 参数将处理作为后台任务运行。
$data = 1..100
$results = @{}
$job = $data | Foreach-Object -Parallel {
$square = $_ * $_
$cube = $_ * $_ * $_
$results = @{
Number = $_
Square = $square
Cube = $cube
}
$using:results[$_] = $results
} -ThrottleLimit 10 -AsJob
$job | Wait-Job
$results.GetEnumerator() | Sort-Object Key | Select-Object -First 5
此示例并行计算平方和立方。结果存储在共享的哈希表中。-AsJob 参数启用后台处理。最终输出显示前 5 个计算结果。
来源
本教程涵盖了 PowerShell 中的 Foreach-Object -Parallel cmdlet。并行处理可以显著提高脚本性能。请记住在线程数与系统资源之间取得平衡。正确的错误处理可确保可靠的并行执行。
作者
列出 所有 PowerShell 教程。