Home Dashboard Directory Help
Search

GetNewClosure doesn't work on Register-ObjectEvent by stej


Status: 

Active


6
0
Sign in
to vote
Type: Bug
ID: 541754
Opened: 3/13/2010 12:24:12 PM
Access Restriction: Public
1
Workaround(s)
view
4
User(s) can reproduce this bug

Description

GetNewClosure works in simple cases without problems.
But when I try to use the scriptblock as -Action for Register-ObjectEvent, the scriptblock doesn't work with the 'frozen' variables.

How to reproduce it:

# first create a timer and register scriptblock that with every tick prints value of $i
$timer = New-Object Timers.Timer
$timer.Interval = 1000
$i = 1;
Register-ObjectEvent $timer Elapsed -Action { write-host 'i: ' $i }.GetNewClosure()
$timer.Enabled = 1

# wait several seconds to see that it is writing 'i: 1'
# change value of $i
$i = 2

# now it is writing 'i: 2'
# so it seems that GetNewClosure didn't capture the state of $i
Details
Sign in to post a comment.
Posted by Russ.J on 6/21/2011 at 6:06 AM
I'd like to note that the workaround I posted does *not* work with Register-EngineEvent for some reason. $block evaluates to $Null in that case. However, it *does* work in the case of this example. If I find a workaround for Register-EngineEvent I'll post that as well.
Sign in to post a workaround.
Posted by Russ.J on 6/21/2011 at 5:36 AM
Since it seems GetNewClosure works in every other context, create a closure outside Register-ObjectEvent and execute it inside the Action block.

# first create a timer and register scriptblock that with every tick prints value of $i
$timer = New-Object Timers.Timer
$timer.Interval = 1000
$i = 1;
$block = { write-host 'i: ' $i }.GetNewClosure()
Register-ObjectEvent $timer Elapsed -Action { &$block }
$timer.Enabled = 1

# wait several seconds to see that it is writing 'i: 1'
# change value of $i
$i = 2

# The timer continues writing 'i: 1'