powershell - 如何退出 ForEach-Object Parallel 并更新 Powershell 7 中运行空间之外的变量?

标签 powershell parallel-processing runspace foreach-object

下面的代码隔离了我正在尝试执行的任务。 一旦在 $loopMe 中检查到超过 3 的数字,我希望 foreach-object 循环在所有运行空间中结束,并将 numberOverLimit 的值设置为 true。

$loopMe = [System.Collections.ArrayList]@()
for($index = 0; $index -lt 5; $index++){
  $loopMe.Add($index)>$null;
}
$global:numberOverLimit=$false
$addToMe= [System.Collections.Concurrent.ConcurrentBag[psobject]]::new() 
$loopMe | Foreach-Object -ThrottleLimit 6 -Parallel{
  $localAddToMe=$using:addToMe
  Write-Host $_
  if($_ -gt 3){
    $global:numberOverLimit=$true
    break
  }
  $localAddToMe.Add($_)
}
write-Host $addToMe
Write-Host $numberOverLimit
if($numberOverLimit){
    Write-Host "A number was over the limit"
    exit
}
else{
    Write-Host "All is good"
}

预期结果

0
1
2
3
3 2 1 0
True
A number was over the limit

实际结果

0
1
4
2
3
3 2 1 0
False
All is good

最佳答案

您的并行循环看不到您的 $global:numberOverLimit 变量,即使可以看到,它也无法更新 bool 值(a value type )。您只能更新reference type来自并行循环,这就是我在本例中使用 Get-Variable 的原因。

另请注意,使用 break in a script block :

Using break inside a pipeline break, such as a ForEach-Object script block, not only exits the pipeline, it potentially terminates the entire runspace.

提早停止管道的唯一内置方法是使用Select-Object -First,您可以将并行循环通过管道传输到它,并将任何内容输出到 stdout 以终止并行循环:

最后,您应该在更新 PSVariable 实例之前确保线程安全,因为您需要使用某种锁定机制,Monitor.Enter就是本例中使用的。

$addToMe = [System.Collections.Concurrent.ConcurrentBag[psobject]]::new()
$numberOverLimit = $false
$psvar = Get-Variable numberOverLimit

0..5 | ForEach-Object -ThrottleLimit 6 -Parallel {
    $localAddToMe = $using:addToMe
    $psvar = $using:psvar

    Write-Host $_

    if($_ -gt 3) {
        [System.Threading.Monitor]::Enter($psvar)
        $psvar.Value = $true
        [System.Threading.Monitor]::Exit($psvar)
        return 'something, whatever here'
    }

    $localAddToMe.Add($_)
} | Select-Object -First 1 | Out-Null

Write-Host $addToMe
Write-Host $numberOverLimit
if($numberOverLimit) {
    Write-Host 'A number was over the limit'
    return
}
else {
    Write-Host 'All is good'
}

关于powershell - 如何退出 ForEach-Object Parallel 并更新 Powershell 7 中运行空间之外的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76100138/

相关文章:

c++ - 从 GPU 复制到 CPU 比从 CPU 复制到 GPU 慢

arrays - 将项目就地分类为段

powershell - RunSpace及其关闭

memory - Powershell:在运行空间 session 中创建文件

python - 使用 python 获取 Azure 服务总线的计数

shell - PowerShell 中类似 GetOpt 的行为

PowerShell DSC 复合资源

c++ - 如何在大函数内编写多线程函数?

powershell - 如何根据组扩展属性获取用户所属的所有组

wpf - 如何调用在 Powershell 中另一个运行空间中运行的 WPF 表单元素的方法