【问题标题】:How do you pass a variable by reference within Start-Job?如何在 Start-Job 中通过引用传递变量?
【发布时间】:2019-03-28 23:29:18
【问题描述】:

如何修改Start-Job 中的变量?这段代码输出0,貌似是因为变量是传值的:

$vara = "0"

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

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

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

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

【问题讨论】:

  • 我以为我知道,但我所知道的都不起作用。一种非常低效的方法是将变量保存到文件中,然后从文件中提取它们。作业在他们自己的 powershell 版本中,这就是它变得棘手的原因。我尝试了全局、本地、私有、脚本等。似乎没有人将其传递回脚本。
  • @RobertCotterman 是的,也想过使用文件。但我们可以希望微软实现这样一个基本的 pass-by-ref 案例......
  • 我认为你想要“同步变量”。看看这篇文章... 在 PowerShell 运行空间之间共享变量和活动对象 |学习 Powershell |实现更多 — learn-powershell.net/2013/04/19/…
  • @Lee_Dailey 这真的可以让您在父会话和子会话之间同步变量吗?以这样一种方式,您可以通过运行空间实际修改父变量?我认为这是为了在多个孩子之间同步变量。例如,您可能创建了 100 个工作并希望环境保持不变。
  • @JacobColvin - 据我所知,是的。看看链接文章中的这句话......“我还将父主机运行空间添加到子运行空间中,因此我可以使用 WriteVerboseLine() 方法将值写入父会话。” ///// 不幸的是,我了解实际发生的情况。在我看来,它就像 OP 想要的那样。

标签: powershell parameters pass-by-reference


【解决方案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

【讨论】:

  • 这是一个很好的解决方法。 +1 但是这种只玩返回值的技巧可能不太适用于工作中的复杂算法。或者在作业结束之前进行并行性和修改值。有没有按引用传递的机制?
  • 好吧,您可以使用$using: 范围,但您不能设置这些变量。一般来说,您应该始终使用我的方法 2 组装输出。无论如何,这只是最佳实践。
猜你喜欢
  • 1970-01-01
  • 2023-01-02
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
相关资源
最近更新 更多