Ticker Stop behaviour in Golang

前端 未结 4 550
遇见更好的自我
遇见更好的自我 2020-12-25 14:48

If I am ranging over a ticker channel and call stop() the channel is stopped but not closed.

In this Example:

package main

import (
    \"time\"
            


        
相关标签:
4条回答
  • 2020-12-25 15:04

    Used a second channel as Volker suggested. This is what I ended up running with:

    package main
    
    import (
        "log"
        "time"
    )
    
    // Run the function every tick
    // Return false from the func to stop the ticker
    func Every(duration time.Duration, work func(time.Time) bool) chan bool {
        ticker := time.NewTicker(duration)
        stop := make(chan bool, 1)
    
        go func() {
            defer log.Println("ticker stopped")
            for {
                select {
                case time := <-ticker.C:
                    if !work(time) {
                        stop <- true
                    }
                case <-stop:
                    return
                }
            }
        }()
    
        return stop
    }
    
    func main() {
        stop := Every(1*time.Second, func(time.Time) bool {
            log.Println("tick")
            return true
        })
    
        time.Sleep(3 * time.Second)
        log.Println("stopping ticker")
        stop <- true
        time.Sleep(3 * time.Second)
    }
    
    0 讨论(0)
  • 2020-12-25 15:06

    you can do like this.

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func startTicker(f func()) chan bool {
        done := make(chan bool, 1)
        go func() {
            ticker := time.NewTicker(time.Second * 1)
            defer ticker.Stop()
            for {
                select {
                case <-ticker.C:
                    f()
                case <-done:
                    fmt.Println("done")
                    return
                }
            }
        }()
        return done
    }
    
    func main() {
        done := startTicker(func() {
            fmt.Println("tick...")
        })
        time.Sleep(5 * time.Second)
        close(done)
        time.Sleep(5 * time.Second)
    }
    
    0 讨论(0)
  • 2020-12-25 15:12

    If You need to save more space use channels of empty structs - struct{} which costs no memory. And as mentioned above don.t send something in it - just close, which actually send zero value.

    0 讨论(0)
  • 2020-12-25 15:25

    Signal "done" on a second channel and select in your goroutine between ticker and done channel.

    Depending on what you really want to do a better solution might exist, but this is hard to tell from the reduced demo code.

    0 讨论(0)
提交回复
热议问题