ScriptBlock.GetNewClosure() 行为 [英] ScriptBlock.GetNewClosure() Behavior
问题描述
我想弄清楚 ScriptBlock.GetNewClosure() 是如何工作的.基于 this 线程(参见 Stej 的回答)我有这个代码:>
I am trying to figure out how ScriptBlock.GetNewClosure() works. Based on this thread (see Stej's answer) I have this code:
$i = 1
$block1 =
{
$i
}
$i = 2
$block2 =
{
$i
}
$i = 3
$block3 =
{
$i
}
& $block1
& $block2
& $block3
输出为:
3
3
3
这是预期的,因为当执行 ScriptBlocks 时,会使用当前的 $i 值.这可以使用 GetNewClosure() 进行更改:
which is expected, because when the ScriptBlocks are executed the current $i value is used. This can be changed using GetNewClosure():
$i = 1
$block1 =
{
$i
}.GetNewClosure()
$i = 2
$block2 =
{
$i
}.GetNewClosure()
$i = 3
$block3 =
{
$i
}.GetNewClosure()
& $block1
& $block2
& $block3
这次的输出是:
1
2
3
这很好,但是当我尝试将 ScriptBlocks 标记为作业时:
This is good, but when I try to star the ScriptBlocks as jobs:
$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 闭包只在同一个 sessionstate/scope 链中起作用
There is no output. Searching for an answer, I found this thread, where x0n says that jobs are executed in a dynamic module. Modules have isolated sessionstate, and share access to globals. PowerShell closures only work within the same sessionstate / scope chain
这是否意味着 $i 不能从作业访问?当我测试它的价值时:
Does this mean that $i is not accessible from jobs? When I test its value:
$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.
推荐答案
是的,这意味着无法通过这种方式从作业中访问 $i
.很遗憾.因此,使用另一种方式:例如,在要作为作业调用的脚本块中的 param
和 Start-Job
的 ArgumentList
参数:
Yes, it means that $i
is not accessible from jobs in this way. Unfortunately. So, use another way: for example, param
in a script block to be invoked as a job and ArgumentList
parameter of Start-Job
:
$i = 42
$block1 =
{
param($i)
$i * 2
}
$job1 = Start-Job $block1 -ArgumentList $i
$job1 | Wait-Job | Receive-Job
输出:
84
附言据报道,GetNewClosure
也不适用于 Register-ObjectEvent
:https://connect.microsoft.com/PowerShell/feedback/details/541754/getnewclosure-doesnt-work-on-register-objectevent
P.S. It is reported that GetNewClosure
also does not work with Register-ObjectEvent
:
https://connect.microsoft.com/PowerShell/feedback/details/541754/getnewclosure-doesnt-work-on-register-objectevent
这篇关于ScriptBlock.GetNewClosure() 行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!