New closure on scriptblock New closure on scriptblock powershell powershell

New closure on scriptblock


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)


I think you are making assumptions that don't hold. PSH is interpreted, so when a code block is created it just holds the source code. When it is later evaluated any variables it uses will be looked up in the normal PSH way: first in the current scope, and then in each outer scope until a variable with a matching name if found.

When the timer fires its event, it executes the code block and thus looks up $i. Which is found in the outer scope with a value of 2.

In the second case, if you just use the code block directly (remove call to GetNewClosure) then the second execution gives 2.


Use global variables in that case:

PS> $global:i = 1PS> $timer = New-Object Timers.TimerPS> $timer.Interval = 1000PS> Register-ObjectEvent $timer Elapsed -Action { write-host 'i: ' $global:i }.GetNewClosure()PS> $timer.Enabled = 1i:  1i:  1i:  1PS> Set-Variable -Name i -Value 2 -Scope Globali:  2i:  2i:  2

Source:

http://stackoverflow.com/q/12535419/1287856