Skip to content

Instantly share code, notes, and snippets.

@semuserable
Last active August 31, 2016 16:16
Show Gist options
  • Save semuserable/0edfaac3b673cd8de05f867a591cc57d to your computer and use it in GitHub Desktop.
Save semuserable/0edfaac3b673cd8de05f867a591cc57d to your computer and use it in GitHub Desktop.
type AsyncTimer(duration) =
let tickEvent = new Event<_>()
let endEvent = new Event<_>()
[<CLIEvent>]
member this.Tick = tickEvent.Publish
[<CLIEvent>]
member this.End = endEvent.Publish
member private this.CancellationToken interval =
let cts = new CancellationTokenSource()
let task = async {
while true do
do! Async.Sleep interval
tickEvent.Trigger(this)
}
Async.StartImmediate(task, cts.Token)
async {
do! Async.Sleep (duration * 1000)
cts.Cancel()
tickEvent.Trigger(this)
endEvent.Trigger(this)
} |> Async.StartImmediate
member private this.MutableLoop interval =
let startingTime = DateTime.Now
let mutable isLooping = true
async {
while isLooping do
do! Async.Sleep interval
let timeExceeded = DateTime.Now - startingTime >= TimeSpan.FromSeconds(float duration)
if timeExceeded then isLooping <- false
tickEvent.Trigger(this)
if not isLooping then endEvent.Trigger(this)
} |> Async.StartImmediate
member this.Start = this.CancellationToken
// Usage
let timer = AsyncTimer(5)
timer.Tick.Add (fun _ -> printfn "%A" DateTime.Now)
timer.End.Add (fun _ -> printfn "Finished!")
timer.Start 1000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment