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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With