简体   繁体   中英

How do I close the timer channel?

I have a timer which is reset by certain events. A go function listens to the channel using range. How do I close the channel so that for loop exits?

func resetTimer(){
        if rf.electionTimer != nil {
             rf.electionTimer.Stop()
        }
}

rf.electionTimer = time.NewTimer(electionTime) 


for _ = range rf.electionTimer.C {
  // Do something
}

Use a channel to signal when the loop should exit.

rf.done := make(chan struct{})
rf.electionTimer = time.NewTimer(electionTime) 

func stopTimer(){
    if rf.electionTimer != nil {
         rf.electionTimer.Stop()
         close(rf.done)
    }
}

Select on both the signal channel and the timer channel in a loop. Break out of the loop when signal channel is closed.

loop:
    for {
        select {
        case t := <-rf.electionTimer.C:
            // Do something
        case <-rf.done:
            break loop
        }
    }

Note that it does not make sense to use a loop in the question or this answer if the application does not call Reset on the timer. If the timer is not reset, then only one value will be sent to the timer's channel.

The channel from the timer does not output a time several times. It will only output a time once after the timer has ended. Therefore, it is useless to use the rf.electionTimer in a for loop.

Try replacing your for loop with:

t := <-rf.electionTimer.C
// Do something with t

This will pause execution until the timer has stopped.

Keep in mind, using rf.electionTimer.Stop() will prevent the timer from ever ending and your <-rf.electionTimer.C line will freeze.

How do I close the channel so that for loop exits?

To prevent the <-rf.electionTimer.C from preventing execution of code, I suggest you use:

rf.electionTimer.Reset(0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM