脚本块上的新闭包 [英] New closure on scriptblock

查看:89
本文介绍了脚本块上的新闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑此代码:

  PS> $ timer = New-Object Timers.Timer 
PS> $ timer.Interval = 1000
PS> $ i = 1;
PS> Register-ObjectEvent $ timer Elapsed -Action {write-host'i:'$ i} .GetNewClosure()
PS> $ timer.Enabled = 1
i:1
i:1
i:1
...
#等待几秒钟并更改$ i
PS> ; $ i = 2
i:2
i:2
i:2

我假设当我创建新的闭包( {write-host'i:'$ i} .GetNewClosure() / code>将绑定到这个闭包。但不是在这种情况下。 Afer我改变值, write-host 接受新值。



另一方面,

  PS> $ i = 1; 
PS> $ action = {write-host'i:'$ i} .GetNewClosure()
PS> & $ action
i:1
PS> $ i = 2
PS> & $ action
i:1

为什么不能使用 Register-ObjectEvent

解决方案

模块具有隔离的会话状态,并且共享对全局的访问。 PowerShell闭包只在同一个会话状态/范围链内工作。恼人,是的。



我说jobs,因为事件处理程序是有效的本地作业,没有不同于使用start-job运行脚本(仅本地计算机,隐式,不使用-computer localhost)


Consider this code:

PS> $timer = New-Object Timers.Timer
PS> $timer.Interval = 1000
PS> $i = 1;
PS> Register-ObjectEvent $timer Elapsed -Action { write-host 'i: ' $i }.GetNewClosure()
PS> $timer.Enabled = 1
i:  1
i:  1
i:  1
 ...
# wait a couple of seconds and change $i
PS> $i = 2
i:  2
i:  2
i:  2

I assumed that when I create new closure ({ write-host 'i: ' $i }.GetNewClosure()) value of $i will be tied to this closure. But not in this case. Afer I change the value, write-host takes the new value.

On the other side, this works:

PS> $i = 1;
PS> $action = { write-host 'i: ' $i }.GetNewClosure()
PS> &$action
i:  1
PS> $i = 2
PS> &$action
i:  1

Why it doesn't work with the Register-ObjectEvent?

解决方案

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. Annoying, yes.

-Oisin

p.s. I say "jobs" because event handlers are effectively local jobs, no different than script being run with start-job (local machine only, implicit, not using -computer localhost)

这篇关于脚本块上的新闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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