I'm using the PowerShell ISE (PS version 5.0). If I run this code:
Write-Host "This"
It outputs:
This
If I modify the script like this:
Write-Host "That"
It outputs:
That
Great. As expected. Now, if I have this code:
$Form = New-Object System.Windows.Forms.Form
$Timer = New-Object System.Windows.Forms.Timer
$Timer.Add_Tick(
{
&{
Write-Output "Here"
$Form.Close()} | Write-Host
})
$Timer.Interval = 3000
$Timer.start()
$result = $Form.ShowDialog()
It outputs:
Here
If I change anything in the script, e.g. "Here"
to "There"
or $Timer.Interval = 3000
to $Timer.Interval = 4000
and run it, it does two unexpected things: 1.) instead of showing the form for the proper duration of time, it briefly flashes it on the screen, and 2.) it outputs the original Here
instead of There
. If I close the ISE and re-open it, the script runs as expected.
What is going on?
tl;dr:
The timer instance is created in the session scope,
Always dispose of a timer (or at least disable it) to prevent it from generating more events.
Generally - although that is not the cause of the problem at hand - be aware that running a script in the ISE implicitly dot-sources it, so that repeated executions run in the same scope, with variable values from previous ones lingering, which can lead to unexpected behavior.
Your code never disposes of (or disables) the timer, which therefore:
stays alive for the entire session, whether or not a variable references it
continues to generate events,
but they only fire while a form is being displayed.
This explains your symptom: The queued up, original events fire instantly as soon as you display the form again.
The solution is to dispose of the timer once it has done its duty and fired the event (once):
Add-Type -AssemblyName System.Windows.Forms
$Form = New-Object System.Windows.Forms.Form
$Timer = New-Object System.Windows.Forms.Timer
$Timer.Add_Tick({
& {
Write-Output "Here"
$Form.Close()
} | Write-Host
})
$Timer.Interval = 3000
$Timer.Start()
$result = $Form.ShowDialog()
$Timer.Dispose() # IMPORTANT: Dispose of the timer so it won't generate more events.
Even with the implicit sourcing behavior of the ISE described above, repeated invocations of this code work as expected.
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