Timers in F#
open System
open System.Threading
open System.Threading.Tasks
let main() =
// Timers represent a single event in the future. You
// tell the timer how long you want to wait, and it
// provides a Task that will complete at that time.
// This timer will wait 2 seconds.
let timer1 = Task.Delay(TimeSpan.FromSeconds(2.0))
// The Await blocks until the task completes,
// indicating that the timer fired.
timer1.Wait()
printfn "Timer 1 fired"
// If you just wanted to wait, you could have used
// Thread.Sleep. One reason a timer may be useful is
// that you can cancel it before it fires.
// Here's an example of that.
let cts = new CancellationTokenSource()
let timer2 = Task.Delay(TimeSpan.FromSeconds(1.0), cts.Token)
// Start a task that will wait for the timer
let timer2Task = Task.Run(fun () ->
try
timer2.Wait()
printfn "Timer 2 fired"
with
| :? OperationCanceledException -> ()
)
// Cancel the timer
cts.Cancel()
if cts.IsCancellationRequested then
printfn "Timer 2 stopped"
// Give the timer2 enough time to fire, if it ever
// was going to, to show it is in fact stopped.
Thread.Sleep(TimeSpan.FromSeconds(2.0))
main()
This F# code demonstrates the use of timers, which are represented by Task.Delay
in F#. Here’s a breakdown of the translation:
We use
Task.Delay
to create a timer that will complete after a specified duration.The
Wait()
method is used to block until the timer completes.For the second timer, we use a
CancellationTokenSource
to allow cancellation.We start a separate task to wait for the second timer, wrapping it in a try-catch block to handle cancellation.
We use
Thread.Sleep
at the end to give enough time for the second timer to fire if it wasn’t cancelled.
The first timer will fire ~2s after we start the program, but the second should be stopped before it has a chance to fire.
To run the program, save it as Timers.fsx
and use the F# interpreter:
$ dotnet fsi Timers.fsx
Timer 1 fired
Timer 2 stopped
This example demonstrates basic timer functionality in F#, including creating timers, waiting for them to complete, and cancelling them before they fire.