Tickers in F#

Timers are for when you want to do something once in the future - tickers are for when you want to do something repeatedly at regular intervals. Here’s an example of a ticker that ticks periodically until we stop it.

open System
open System.Threading

let main() =
    // Tickers use a similar mechanism to timers: a
    // value that is sent at regular intervals. Here we'll use an
    // async workflow to await the values as they arrive every 500ms.
    let ticker = new Timer(callback = (fun _ -> 
        printfn "Tick at %s" (DateTime.Now.ToString())), 
        state = null, 
        dueTime = TimeSpan.Zero, 
        period = TimeSpan.FromMilliseconds(500.0))
    
    let mutable shouldStop = false
    
    async {
        while not shouldStop do
            do! Async.Sleep 100 // Small delay to prevent busy waiting
    } |> Async.Start
    
    // Tickers can be stopped. Once a ticker
    // is stopped it won't receive any more values.
    // We'll stop ours after 1600ms.
    Thread.Sleep(1600)
    ticker.Dispose()
    shouldStop <- true
    printfn "Ticker stopped"

main()

When we run this program the ticker should tick 3 times before we stop it.

$ dotnet run
Tick at 5/30/2023 10:15:30 AM
Tick at 5/30/2023 10:15:31 AM
Tick at 5/30/2023 10:15:31 AM
Ticker stopped

In this F# version, we use the System.Threading.Timer class to create a ticker that fires every 500 milliseconds. We use an async workflow to keep the program running until we decide to stop it. After 1600 milliseconds, we dispose of the timer and set a flag to stop the async workflow.

Note that F# doesn’t have built-in channels like Go, so we’ve adapted the example to use a timer callback instead. The overall behavior of periodically executing a task remains the same.