如何停止golang中的周期函数

How to stop a periodic function in golang

所以我有一个函数,每 2 秒调用一次。像这样

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)
}

现在假设我不再希望此函数每 2 秒执行一次。有没有办法在 golang 中实现这个?或者有没有比这更好的方法来调用 golang 中的周期函数?谢谢。

time.Tick() 的文档声明它无法停止:

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".

如果您需要停止它,请改用 time.NewTicker()。 运行 doEvery() 在一个新的 goroutine 中,并传递一个通道给它,这让你有办法停止它,例如通过关闭频道:

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)
        }
    }
}

正在测试:

done := make(chan bool)
go doEvery(300*time.Millisecond, done, helloworld)

time.Sleep(time.Second)
close(done)

time.Sleep(time.Second)
fmt.Println("Quitting")

这将输出(在 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