ScriptBlock.GetNewClosure()行为

时间:2010-10-30 12:38:20

标签: powershell

我想弄清楚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。

2 个答案:

答案 0 :(得分:7)

是的,这意味着以这种方式无法从作业访问$i。不幸。因此,使用另一种方式:例如,作为作业调用的脚本块中的paramArgumentList的{​​{1}}参数:

Start-Job

输出:

$i = 42
$block1 =
{
    param($i)
    $i * 2
}

$job1 = Start-Job $block1 -ArgumentList $i
$job1 | Wait-Job | Receive-Job

P.S。据报道84 也不适用于GetNewClosurehttps://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

http://www.powertheshell.com/closure/