以下是工作代码:
$ids = 1..9
$status = [PSCustomObject[]]::new(10)
foreach ($id in $ids)
{
$uriStr = "http://192.168." + [String]$id + ".51/status"
$uri = [System.Uri] $uriStr
$status[$id] = try {Invoke-RestMethod -Uri $uri -TimeOut 30}catch{}
}
$status
我想并行执行 for 循环以探索性能改进。
我尝试的第一件事(结果很天真)就是简单地引入 -parallel 参数
$ids = 1..9
$status = [PSCustomObject[]]::new(10)
foreach -parallel ($id in $ids)
{
$uriStr = "http://192.168." + [String]$id + ".51/status"
$uri = [System.Uri] $uriStr
$status[$id] = try {Invoke-RestMethod -Uri $uri -TimeOut 30}catch{}
}
$status
这会导致以下错误,表明从 Powershell 7.3.9 开始,此功能仍在考虑开发中:
ParserError:
Line |
3 | foreach -parallel ($id in $ids)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The foreach '-parallel' parameter is reserved for future use.
我说天真,因为文档说并行参数仅在工作流程中有效。但是,当我尝试时,我收到一条错误消息,指出不再支持工作流程。
workflow helloworld {Write-Host "Hello World"}
ParserError:
Line |
1 | workflow helloworld {Write-Host "Hello World"}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Workflow is not supported in PowerShell 6+.
然后我尝试了各种参考资料中的各种组合(好例子),其中关于 ForEach 的建议与 ForEach-Object 根本不同,ForEach-Object 支持并行,就像这样(基本上是通过管道将 id 输入):
$ids = 1..9
$status = [PSCustomObject[]]::new(10)
$ids | ForEach-Object -Parallel
{
$uriStr = "http://192.168." + [String]$_ + ".51/status"
$uri = [System.Uri] $uriStr
$status[$_] = try {Invoke-RestMethod -Uri $uri -TimeOut 30}catch{}
}
$status
这会生成以下错误:
ForEach-Object:
Line |
3 | $ids | foreach-object -parallel
| ~~~~~~~~~
| Missing an argument for parameter 'Parallel'. Specify a parameter of type
| 'System.Management.Automation.ScriptBlock' and try again.
$uriStr = "http://192.168." + [String]$_ + ".51/status"
$uri = [System.Uri] $uriStr
$status[$i_] = try {Invoke-RestMethod -Uri $uri -TimeOut 30}catch{}
但是,在尝试了各种脚本块语义之后,这是我能做的最好的事情(基本上应用 :using 到脚本块之外的状态变量):
$ids = 1..9
$status = [PSCustomObject[]]::new(10)
$myScriptBlock =
{
$uriStr = "http://192.168." + [String]$_ + ".51/status"
$uri = [System.Uri] $uriStr
{$using:status}[$_] = try {Invoke-RestMethod -Uri $uri -TimeOut 30}catch{}
}
$ids | foreach-object -parallel $myScriptBlock
$status
再次出错:
Line |
4 | … ng:status}[$_] = try {Invoke-RestMethod -Uri $uri -TimeOut 30}catch{}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Unable to index into an object of type "System.Management.Automation.ScriptBlock".
InvalidOperation:
查看使用脚本块、
并将您的最后一次尝试更改为:
$ids = 1..9
$status = [PSCustomObject[]]::new(10)
$myScriptBlock =
{
$uriStr = "http://192.168." + [String]$_ + ".51/status"
$uri = [System.Uri] $uriStr
{$using:status}[$_] = try {Invoke-RestMethod -Uri $uri -TimeOut 30}catch{}
}
$ids | foreach-object -parallel $myScriptBlock
$status
至:
$ids = 1..9
$status = [PSCustomObject[]]::new(10)
$ids | foreach-object -parallel {
$uriStr = "http://192.168." + [String]$_ + ".51/status"
$uri = [System.Uri] $uriStr
{$using:status}[$_] = try {Invoke-RestMethod -Uri $uri -TimeOut 30}catch{}
}
$status
似乎能让你更进一步