在使用 Start-ThreadJob 启动的线程中修改 PowerShell $using 范围变量
Modifying PowerShell $using scope variables in thread started with Start-ThreadJob
如果我理解 PowerShell Scopes documentation,应该可以从使用 Start-ThreadJob
开始的线程分配给 $using
范围变量。文档说(强调我的):
The Using
scope modifier is supported in the following contexts:
- ...
- Thread jobs, started via
Start-ThreadJob
or ForEach-Object -Parallel
(separate thread session)
Depending on the context, embedded variable values are either independent copies of the data in the caller's scope or references to it.
...
In thread sessions, they are passed by reference. This means it is possible to modify call scope variables in a different thread. To safely modify variables requires thread synchronization.
但以下内容无法 运行:
$foo = 1
Start-ThreadJob {
Write-Host $using:foo
$using:foo = 2
} | Wait-Job | Out-Null
Write-Host $foo
它在 $using:foo = 2
上出错:
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.
使用 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 倍)值
如果我理解 PowerShell Scopes documentation,应该可以从使用 Start-ThreadJob
开始的线程分配给 $using
范围变量。文档说(强调我的):
The
Using
scope modifier is supported in the following contexts:
- ...
- Thread jobs, started via
Start-ThreadJob
orForEach-Object -Parallel
(separate thread session)Depending on the context, embedded variable values are either independent copies of the data in the caller's scope or references to it.
...
In thread sessions, they are passed by reference. This means it is possible to modify call scope variables in a different thread. To safely modify variables requires thread synchronization.
但以下内容无法 运行:
$foo = 1
Start-ThreadJob {
Write-Host $using:foo
$using:foo = 2
} | Wait-Job | Out-Null
Write-Host $foo
它在 $using:foo = 2
上出错:
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.
使用 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