lucky yang
lucky yang

Reputation: 1669

Does a ticker tell a goroutine it is stopped through its ticker.C?

package main
import "fmt"
import "time"

func main() {
    ticker := time.NewTicker(time.Millisecond * 500)
    go func() {
        for t := range ticker.C {
            fmt.Println("Tick at", t)
        }
        fmt.Println("ticker stopped")
    }()
    time.Sleep(time.Second * 5)
    ticker.Stop()
    time.Sleep(time.Second * 5)
}

I thought when I call ticker.Stop(), ticker.C should tell the goroutine that it is over, so the for loop should end, but it doesn't look like that, the string "ticker stopped" is never printed.

Upvotes: 1

Views: 3134

Answers (1)

Kaedys
Kaedys

Reputation: 10128

As JimB pointed out, the documentation for the time.Ticker specifies that Stop() does not close the channel, to prevent a read from the channel succeeding incorrectly. Your best bet is probably a quit channel.

package main

import "fmt"
import "time"

func main() {
    ticker := time.NewTicker(time.Millisecond * 500)
    quit := make(chan struct{})
    go func() {
        for {
            select {
            case t := <-ticker.C:
                fmt.Println("Tick at", t)
            case <-quit:
                fmt.Println("ticker stopped")
                return
            }
        }
    }()
    time.Sleep(time.Second * 5)
    ticker.Stop()
    close(quit)
    time.Sleep(time.Second * 5)
}

https://play.golang.org/p/xTKNkMtdIf

Upvotes: 1

Related Questions