ScriptBlock.GetNewClosure() 行为 [英] ScriptBlock.GetNewClosure() Behavior

查看:55
本文介绍了ScriptBlock.GetNewClosure() 行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想弄清楚 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.很遗憾.因此,使用另一种方式:例如,在要作为作业调用的脚本块中的 paramStart-JobArgumentList 参数:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆