Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Debounce Function in PowerShell

I’m attempting to create a simple debounce function in PowerShell. Here is what I have so far.

# timer.ps1
# Define debounce function
Function New-Debounce {
    param(
        [scriptblock]$ScriptBlock,
        [int]$DelayMilliseconds
    )
    
    $timer = $null
    $id = $null

    return {
        # reset timer
        if ($timer) { 
            $timer.Stop() 
            $timer.Dispose()
        }

        $timer = [System.Timers.Timer]::new($DelayMilliseconds)
        # only fire once
        $timer.AutoReset = $false

        $timer.Start()

        # Listen for the Elapsed event and execute our script block when it occurs
        $id = Register-ObjectEvent `
            -InputObject $timer `
            -EventName "Elapsed" `
            -SourceIdentifier "Timer.Debounce" `
            -Action { Write-Host "Hello!"; & $ScriptBlock }
    }.GetNewClosure()
}

$f = New-Debounce -ScriptBlock { Write-Host "There" } -DelayMilliseconds 1000
& $f

# # Keep the process alive so the timer can do its thing
for ($i = 0; $i -lt 5; $i++) {
    Start-Sleep -Seconds 1
}

Unregister-Event "Timer.Debounce"

Running timer.ps1 always outputs "Hello" but never "There", and I’m unsure why.

Why would my passed $ScriptBlock not be executed when the timer fires? How would you improve this code?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Use -MessageData to pass in the $ScriptBlock to the Action block:

# Listen for the Elapsed event and execute our script block when it occurs
$registerObjectEventSplat = @{
    InputObject      = $timer
    EventName        = 'Elapsed'
    SourceIdentifier = 'Timer.Debounce'
    MessageData      = $ScriptBlock
    Action           = { Write-Host 'Hello!'; & $event.MessageData }
}

$id = Register-ObjectEvent @registerObjectEventSplat
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading