PowerShell“foreach-object -Parallel”从循环中获取变量值

问题描述 投票:0回答:3

如何获取“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]

我得到的结果:

enter image description here

powershell parallel.foreach foreach-object
3个回答
1
投票

您定义全局变量的方式不正确。 您应该在

$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]"

enter image description here


0
投票

(如果您确实想运行

-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
  }
]

0
投票

要与 -Parallel 一起使用,我认为您需要 $using: 修饰符以及变量引用

另请参阅 此文档示例结合了 -Parallel 和 $using

例如:

$limitReached = $False
$limitReachedRef = [ref] $limitReached
1..2 | ForEach-Object -Parallel {
    $limitReachedRefCopy = $using:limitReachedRef
    $limitReachedRefCopy.Value = $True
}
$limitReached

输出:

True
© www.soinside.com 2019 - 2024. All rights reserved.