So I have a function that is called after every 2 seconds. Like this
package main
import (
"fmt"
"time"
)
func doEvery(d time.Duration, f func(time.Time)) {
for x := range time.Tick(d) {
f(x)
}
}
func helloworld(t time.Time) {
fmt.Printf("%v: Hello, World!\n", t)
}
func main() {
doEvery(20*time.Millisecond, helloworld)
}
Now lets say I no longer want this function to execute after every 2 seconds. Is there a way I can achieve this in golang? Or is there any better way than this to call a periodic function in golang? Thank you.
CodePudding user response:
Documentation of time.Tick()
states it cannot be stopped:
Tick is a convenience wrapper for NewTicker providing access to the ticking channel only. While Tick is useful for clients that have no need to shut down the Ticker, be aware that without a way to shut it down the underlying Ticker cannot be recovered by the garbage collector; it "leaks".
If you need to stop it, use time.NewTicker()
instead. Run doEvery()
in a new goroutine, and pass a channel to it which gives you a mean to stop it, e.g. by closing the channel:
func doEvery(d time.Duration, done chan bool, f func(time.Time)) {
ticker := time.NewTicker(d)
defer ticker.Stop()
for {
select {
case <-done:
fmt.Println("Done!")
return
case t := <-ticker.C:
f(t)
}
}
}
Testing it:
done := make(chan bool)
go doEvery(300*time.Millisecond, done, helloworld)
time.Sleep(time.Second)
close(done)
time.Sleep(time.Second)
fmt.Println("Quitting")
This will output (try it on the Go Playground):
2009-11-10 23:00:00.3 0000 UTC m= 0.300000001: Hello, World!
2009-11-10 23:00:00.6 0000 UTC m= 0.600000001: Hello, World!
2009-11-10 23:00:00.9 0000 UTC m= 0.900000001: Hello, World!
Done!
Quitting