Skip to content

Instantly share code, notes, and snippets.

@gitfvb
Created September 4, 2020 14:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gitfvb/51bca4b382f1b7c884e6db76de4f1033 to your computer and use it in GitHub Desktop.
Save gitfvb/51bca4b382f1b7c884e6db76de4f1033 to your computer and use it in GitHub Desktop.
A timer in PowerShell controlled through a "tick" event instead of a start-sleep. Script can be run standalone out of the box.
<#
Good example inspired from here
https://gist.github.com/SteveGilham/98a39f621cfed70bfa0a
To explore possible events, type in
$timer | gm
#>
#Write-Host "Press any key to continue..."
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
# Unregister all events
Get-EventSubscriber -Force | Unregister-Event -Force
# Create a timer object with a specific interval and a starttime
$timer = New-Object -Type Timers.Timer
$timer.Interval = 1000 # milliseconds, the interval defines how often the event gets fired
$startTime = Get-Date
# Register an event for every passed interval
Register-ObjectEvent -InputObject $timer -EventName Elapsed -SourceIdentifier "Timer.Elapsed" -MessageData $startTime -Action {
# Input variables and objects
$currentStart = $Event.MessageData
$timer = $Sender
# Calculate current timespan
$timeSpan = New-TimeSpan -Start $currentStart -End ( Get-Date )
# Output the results to console
Write-Host -NoNewLine "`r$( $timeSpan.Seconds )"
#[System.Console]::Write($timeSpan.Seconds)
} | Out-Null
# Start the timer
$timer.Start()
# Stop the time manually
#$timer.Stop()
<#
#-----------------------------------------------
# Keep this process open forever
#-----------------------------------------------
# Just loop forever
while ($true){
Start-Sleep -Seconds 1
}
#>
#-----------------------------------------------
# Keep the process open for a specific amount of time
#-----------------------------------------------
# Registers an Event, that has a timeout
# When timeout is reached, then the timer gets disposed
# and the events get unregistered
Register-ObjectEvent -InputObject $timer -EventName Disposed -SourceIdentifier "Timer.Disposed"
# Wait until timout or timer disposed by another process
if (-not (Wait-Event "Timer.Disposed" -Timeout 10 )) {
Write-Host "`nTimeout"
$timer.Stop()
$timer.Dispose()
} else {
Write-Host "`nDone"
}
# Wait another 5 seconds to see the message
Start-Sleep -Seconds 5
# Tidy event registrations and event queue
# The Elapsed events are spent in the handler
# but the one we wait on must be explicitly cleared
Remove-Event "Timer.Disposed"
Unregister-Event "Timer.Elapsed"
Unregister-Event "Timer.Disposed"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment