如何获取“Foreach-Object”函数/循环之外的“Foreach-Object -Parallel”循环中设置的变量值?在我的示例中,变量
limitReached
最终在 write-host
处没有值。我需要在脚本中使用 While
循环,下面是我正在做的事情的简化版本。
$retries = 2
$secondsDelay = 2
$a = "house"
1..2 | ForEach-Object -Parallel {
$retryCount = 0
$ready = $false
while ($ready -ne $true)
{
if ($a -eq "hello")
{
Write-Output ("a is equal ""hello"".")
$ready = $true
}
else
{
Write-Output ("a is not equal ""hello"".")
if ($retryCount -ge $using:retries)
{
Write-Output ("a is STILL not equal ""hello"".")
$global:limitReached = $true
Write-Host "Checking - limitReached value is [$limitReached]"
return
}
else
{
Write-Output ("let's give more runs.")`n
Start-Sleep $using:secondsDelay
$retryCount++
}
}
}
}
Write-Host "I need this value - limitReached here is [$global:limitReached]"
我期望的结果:
I need this value - limitReached here is [TRUE]
我得到的结果:
您定义全局变量的方式不正确。 您应该在
$a = "house"
下方将其声明为 $limitReached = $false
从代码中删除
$global:
并仅保留变量名称,这样就可以开始了。
这是更新后的代码,提供输出
I need this value - limitReached here is [True]
以及循环输出。
$retries = 2
$secondsDelay = 2
$a = "house"
$limitReached = $false
1..2 | ForEach-Object {
$retryCount = 0
$ready = $false
while ($ready -ne $true)
{
if ($a -eq "hello")
{
Write-Output ("a is equal ""hello"".")
$ready = $true
}
else
{
Write-Output ("a is not equal ""hello"".")
if ($retryCount -ge $retries)
{
Write-Output ("a is STILL not equal ""hello"".")
$limitReached = $true
Write-Host "Checking - limitReached value is [$limitReached]"
return
}
else
{
Write-Output ("let's give more runs.")`n
Start-Sleep $secondsDelay
$retryCount++
}
}
}
}
Write-Host "I need this value - limitReached here is [$limitReached]"
(如果您确实想运行
-Parallel
中的进程)1
和2
)并行运行(并且2
nd线程可能首先完成),您希望返回哪个$limitReached
?
无论如何,您可以使用 [hashtable]::Synchronized(@{})
类,但最简单的可能就是使用 PowerShell 来检索结果:
$Result = 1..2 |ForEach-Object -Parallel {
for ($i = 1; $i -le 4 - $_; $i++) {
Write-Host "Time: $(Get-Date -Format 'HH:mm:ss'), Id: $_, Count: $i"
Sleep -Seconds $i
}
@{
ID = $_
Count = $i
limitReached = $_ -eq 1
}
}
Time: 14:57:17, Id: 1, Count: 1
Time: 14:57:17, Id: 2, Count: 1
Time: 14:57:18, Id: 2, Count: 2
Time: 14:57:18, Id: 1, Count: 2
Time: 14:57:20, Id: 1, Count: 3
$Result |ConvertTo-Json
[
{
"Count": 3,
"ID": 2,
"limitReached": false
},
{
"Count": 4,
"ID": 1,
"limitReached": true
}
]
要与 -Parallel 一起使用,我认为您需要 $using: 修饰符以及变量引用
另请参阅 此文档示例结合了 -Parallel 和 $using
例如:
$limitReached = $False
$limitReachedRef = [ref] $limitReached
1..2 | ForEach-Object -Parallel {
$limitReachedRefCopy = $using:limitReachedRef
$limitReachedRefCopy.Value = $True
}
$limitReached
输出:
True