如何在 Start-Job 中通过引用传递变量?

How do you pass a variable by reference within Start-Job?

提问人:yO_ 提问时间:10/24/2018 最后编辑:alexyO_ 更新时间:8/19/2019 访问量:1125

问:

你如何修改其中的变量?这段代码输出,似乎是因为变量是按值传递的:Start-Job0

$vara = "0"

$j = start-job -ScriptBlock {
   $args[0] = "1"
} -ArgumentList $vara

wait-job $j > $null
receive-job $j

Write-Host $vara  ## => "0"

如何通过引用传递参数(因此输出)?1

参数 按引用传递PowerShell parameters pass-by-reference

评论

0赞 Robert Cotterman 10/24/2018
我以为我知道,但我所知道的都不起作用。一种非常低效的方法是将变量保存到文件中,然后从文件中提取它们。作业在他们自己的 powershell 版本中,这就是它变得棘手的原因。我尝试了全局、本地、私有、脚本等。似乎没有人将其传回脚本。
1赞 yO_ 10/24/2018
@RobertCotterman 是的,也想过使用文件。但我们可以希望Microsoft实现了这样一个基本的通过参考案例......
2赞 Lee_Dailey 10/24/2018
我认为你想要“同步变量”。看看这篇文章...在 PowerShell 运行空间之间共享变量和实时对象 |了解 Powershell |实现更多目标 — learn-powershell.net/2013/04/19/...
0赞 Jacob Colvin 10/24/2018
这实际上@Lee_Dailey允许您在父会话和子会话之间同步变量?这样一来,您实际上可以通过运行空间修改父变量?我以为这是为了在多个孩子之间同步变量。例如,也许你产生了 100 个工作,并希望环境是相同的。
0赞 Lee_Dailey 10/24/2018
@JacobColvin - 从我对这一切的了解来看,是的。看看链接文章中的这句话......“我还将父主机运行空间添加到子运行空间中,这样我就可以使用 WriteVerboseLine() 方法将值写入父会话。” /////不幸的是,我不明白实际发生了什么。在我看来,它似乎做到了 OP 似乎想要的。

答:

4赞 Jacob Colvin 10/24/2018 #1

在修改作业中的任何内容时,您完全超出了范围。没有什么会神奇地填充到您当前的会话中。

你可以做这样的事情:

$vara = "0"

$j = start-job -ScriptBlock {
   "1"
} -ArgumentList $vara

wait-job $j > $null
$vara = receive-job $j

Write-Host $vara

如果你需要填充很多参数,你可以做这样的事情:

$vara = "0"

$j = start-job -ScriptBlock {
   [pscustomobject]@{
      vara1 = "1"
      vara2 = "0"
    }
} -ArgumentList $vara

wait-job $j > $null
$vara = receive-job $j

Write-Host $vara.vara1

评论

0赞 yO_ 10/24/2018
这是一个很好的解决方法。+1 但是这种只使用返回值的技巧,对于作业中的复杂算法来说可能不太有用。或者用于并行性和在作业结束前修改值。没有通过参考机制吗?
0赞 Jacob Colvin 10/24/2018
好吧,您可以使用范围,但不能设置这些变量。通常,您应该始终使用我的方法 2 组装输出。无论如何,这只是最佳实践。$using: