![](/img/trans.png)
[英]Powershell: Runspace/Pool how do i pass a function and shared variable?
[英]How to pass variable by reference to Powershell job or runspace?
我有 Powershell 工作。
$cmd = {
param($a, $b)
$a++
$b++
}
$a = 1
$b = 2
Start-Job -ScriptBlock $cmd -ArgumentList $a, $b
如何通过引用传递$a
和$b
,以便在工作完成后更新它们? 或者如何通过引用传递变量到运行空间?
在PowerShell中,通过引用传递参数总是很尴尬,并且可能无论如何都不适用于PowerShell作业,正如@bluuf所指出的那样。
我可能会这样做:
$cmd = {
Param($x, $y)
$x+1
$y+1
}
$a = 1
$b = 2
$a, $b = Start-Job -ScriptBlock $cmd -ArgumentList $a, $b |
Wait-Job |
Receive-Job
上面的代码将变量$a
和$b
传递给scriptblock,并在收到作业输出后将修改后的值赋给变量。
我刚写的简单示例(不介意凌乱的代码)
# Test scriptblock
$Scriptblock = {
param([ref]$a,[ref]$b)
$a.Value = $a.Value + 1
$b.Value = $b.Value + 1
}
$testValue1 = 20 # set initial value
$testValue2 = 30 # set initial value
# Create the runspace
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ApartmentState = [System.Threading.ApartmentState]::STA
$Runspace.Open()
# create the PS session and assign the runspace
$PS = [powershell]::Create()
$PS.Runspace = $Runspace
# add the scriptblock and add the argument as reference variables
$PS.AddScript($Scriptblock)
$PS.AddArgument([ref]$testValue1)
$PS.AddArgument([ref]$testValue2)
# Invoke the scriptblock
$PS.BeginInvoke()
运行此之后,测试值会更新,因为它们是由ref传递的。
带有示例的更全面的脚本。
$host
或其他东西的能力,从传递的脚本 output 到控制台创建write-host
。 但我没有时间弄清楚如何做到这一点。$v = 1
function newThread ([scriptblock]$script, [Parameter(ValueFromPipeline)]$param, [Parameter(ValueFromRemainingArguments)]$args) {
process {
$Powershell = [powershell]::Create()
$Runspace = [runspacefactory]::CreateRunspace()
# allows to limit commands available there
# $InitialSessionState = InitialSessionState::Create()
# $Runspace.InitialSessionState = $InitialSessionState
$Powershell.Runspace = $Runspace
$null = $Powershell.AddScript($script)
$null = $Powershell.AddArgument($param)
foreach ($v_f in $args) {
$null = $Powershell.AddArgument($v_f)
}
$Runspace.Open()
$Job = $Powershell.BeginInvoke()
[PSCustomObject]@{
Job=$Job
Powershell=$Powershell
}
}
}
$script = {
param([ref]$v,$v2)
$v.Value++
$v2
}
$thread = newThread $script ([ref]$v) 3
do {} until ($thread.Job.IsCompleted)
$v1 = $thread.Powershell.EndInvoke($thread.Job)
$thread.Powershell.Dispose()
write-host "end $($v,$v1[0])"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.