我试图找出ScriptBlock.GetNewClosure()的工作原理.基于这个帖子(参见Stej的回答)我有这个代码:
$i = 1
$block1 =
{
$i
}
$i = 2
$block2 =
{
$i
}
$i = 3
$block3 =
{
$i
}
& $block1
& $block2
& $block3
Run Code Online (Sandbox Code Playgroud)
输出是:
3
3
3
Run Code Online (Sandbox Code Playgroud)
这是预期的,因为当执行ScriptBlocks时,使用当前的$ i值.这可以使用GetNewClosure()更改:
$i = 1
$block1 =
{
$i
}.GetNewClosure()
$i = 2
$block2 =
{
$i
}.GetNewClosure()
$i = 3
$block3 =
{
$i
}.GetNewClosure()
& $block1
& $block2
& $block3
Run Code Online (Sandbox Code Playgroud)
这次输出是:
1
2
3
Run Code Online (Sandbox Code Playgroud)
这很好,但是当我尝试将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
Run Code Online (Sandbox Code Playgroud)
没有输出.在寻找答案时,我找到了这个线程,其中x0n表示作业是在动态模块中执行的.模块具有隔离的会话状态,并共享对全局变量的访问.PowerShell闭包只能在同一个sessionstate/scope链中工作
这是否意味着$ 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
Run Code Online (Sandbox Code Playgroud)
$等于null.
是的,这意味着$i以这种方式无法从作业访问.不幸.因此,使用另一种方式:例如,param在作为作业和ArgumentList参数调用的脚本块中Start-Job:
$i = 42
$block1 =
{
param($i)
$i * 2
}
$job1 = Start-Job $block1 -ArgumentList $i
$job1 | Wait-Job | Receive-Job
Run Code Online (Sandbox Code Playgroud)
输出:
84
Run Code Online (Sandbox Code Playgroud)
PS据报道,它GetNewClosure也无法使用Register-ObjectEvent:https:
//connect.microsoft.com/PowerShell/feedback/details/541754/getnewclosure-doesnt-work-on-register-objectevent
| 归档时间: |
|
| 查看次数: |
1824 次 |
| 最近记录: |