我想弄清楚ScriptBlock.GetNewClosure()是如何工作的。基于this线程(参见Stej的回答)我有这段代码:
$i = 1
$block1 =
{
$i
}
$i = 2
$block2 =
{
$i
}
$i = 3
$block3 =
{
$i
}
& $block1
& $block2
& $block3
输出结果为:
3
3
3
这是预期的,因为当执行ScriptBlocks时,使用当前的$ i值。这可以使用GetNewClosure()来更改:
$i = 1
$block1 =
{
$i
}.GetNewClosure()
$i = 2
$block2 =
{
$i
}.GetNewClosure()
$i = 3
$block3 =
{
$i
}.GetNewClosure()
& $block1
& $block2
& $block3
这次输出是:
1
2
3
这很好,但是当我尝试将ScriptBlocks作为作业加注时:
$i = 1
$block1 =
{
$i
}.GetNewClosure()
$i = 2
$block2 =
{
$i
}.GetNewClosure()
$i = 3
$block3 =
{
$i
}.GetNewClosure()
$job1 = Start-Job $block1
$job1 | Wait-Job
$job1 | Receive-Job
$job2 = Start-Job $block2
$job2 | Wait-Job
$job2 | Receive-Job
$job3 = Start-Job $block3
$job3 | Wait-Job
$job3 | Receive-Job
没有输出。在寻找答案时,我找到了this个线程,其中x0n表示作业是在动态模块中执行的。模块具有隔离的会话状态,并共享对全局变量的访问。 PowerShell闭包只能在同一个会话状态/范围链中工作
这是否意味着$ i无法从作业中访问?当我测试它的值时:
$i = 1
$block1 =
{
$i -eq $null
}.GetNewClosure()
$i = 2
$block2 =
{
$i -eq $null
}.GetNewClosure()
$i = 3
$block3 =
{
$i -eq $null
}.GetNewClosure()
$job1 = Start-Job $block1
$job1 | Wait-Job
$job1 | Receive-Job
$job2 = Start-Job $block2
$job2 | Wait-Job
$job2 | Receive-Job
$job3 = Start-Job $block3
$job3 | Wait-Job
$job3 | Receive-Job
$等于null。
答案 0 :(得分:7)
是的,这意味着以这种方式无法从作业访问$i
。不幸。因此,使用另一种方式:例如,作为作业调用的脚本块中的param
和ArgumentList
的{{1}}参数:
Start-Job
输出:
$i = 42
$block1 =
{
param($i)
$i * 2
}
$job1 = Start-Job $block1 -ArgumentList $i
$job1 | Wait-Job | Receive-Job
P.S。据报道84
也不适用于GetNewClosure
:
https://connect.microsoft.com/PowerShell/feedback/details/541754/getnewclosure-doesnt-work-on-register-objectevent
答案 1 :(得分:-2)
$i = 1
$block1 = {"block 1 is $using:i" }.GetNewClosure()
$i = 2
$block2 = { "block 2 is $using:i" }.GetNewClosure()
$job1 = Start-Job $block1
$job1 | Wait-Job
$job1 | Receive-Job
$job2 = Start-Job $block2
$job2 | Wait-Job
$job2 | Receive-Job