使用Start-ThreadJob启动的线程中的作用域变量修改PowerShell$



如果我了解PowerShell Scopes文档,应该可以从使用Start-ThreadJob启动的线程中为$using范围变量赋值。文件上说(emphasis我的(:

Using作用域修饰符在以下上下文中受支持:

  • 线程作业,通过Start-ThreadJobForEach-Object -Parallel启动(单独的线程会话(

根据上下文的不同,嵌入的变量值要么是调用方作用域中数据的独立副本,要么是对其的引用

在线程会话中,它们是通过引用传递的。这意味着可以在不同的线程中修改调用范围变量要安全地修改变量,需要线程同步。

但是以下操作无法运行:

$foo = 1
Start-ThreadJob {
Write-Host $using:foo
$using:foo = 2
} | Wait-Job | Out-Null
Write-Host $foo

它在$using:foo = 2上错误为:

赋值表达式无效。赋值运算符的输入必须是能够接受赋值的对象,例如变量或属性。

使用Write-Host $using:foo打印变量可以正常工作。

我正在使用PowerShell 7.1。

您不能覆盖$using:变量引用,但您可以使用它来取消引用调用范围中的变量值,然后您可以对其进行变异(假设引用类型值已分配给原始变量(:

$foo = @{ 
Value = 1
}
Start-ThreadJob {
Write-Host $using:foo
$foo = $using:foo
$foo.Value = 2
} | Wait-Job | Out-Null
Write-Host $foo.Value

为了确保线程同步,我建议使用一个同步的哈希表作为容器类型:

$foo = [hashtable]::Synchronized(@{ 
Value = 1
})
1..4 |%{Start-ThreadJob {
Write-Host $using:foo
$foo = $using:foo
$foo.Value++
}} | Wait-Job | Out-Null
Write-Host $foo.Value

此时,您应该看到5的值(增加4倍(

相关内容

  • 没有找到相关文章

最新更新