如何找到计时器触发的剩余时间?

mur*_*uru 0 timer go

我需要在x几秒钟后运行一个函数,并具有一定的控制能力(重置计时器,停止计时器,找到剩余的执行时间)。time.Timer非常合适 - 唯一缺少的是它似乎无法找到还剩多少时间。

我有哪些选择?

目前,我在想这样的事情:

package main

import "time"

type SecondsTimer struct {
    T       time.Duration
    C       chan time.Time
    control chan time.Duration
    running bool
}

func (s *SecondsTimer) run() {
    for s.T.Seconds() > 0 {
        time.Sleep(time.Second)
        select {
        case f := <-s.control:
            if f > 0 {
                s.T = f
            } else {
                s.running = false
                break
            }
        default:
            s.T = s.T - 1
        }
    }
    s.C <- time.Now()
}
func (s *SecondsTimer) Reset(t time.Duration) {
    if s.running {
        s.control <- t
    } else {
        s.T = t
        go s.run()
    }

}
func (s *SecondsTimer) Stop() {
    if s.running {
        s.control <- 0
    }
}
func NewSecondsTimer(t time.Duration) *SecondsTimer {
    time := SecondsTimer{t, make(chan time.Time), make(chan time.Duration), false}
    go time.run()
    return &time
}
Run Code Online (Sandbox Code Playgroud)

现在我可以s.T.Seconds()根据需要使用了。

但我对竞争条件和其他此类问题持谨慎态度。这是要走的路,还是我可以使用更本地化的东西?

Bri*_*orn 5

有一个更简单的方法。你仍然可以使用 atime.Timer来完成你想要的,你只需要跟踪end time.Time

type SecondsTimer struct {
    timer *time.Timer
    end   time.Time
}

func NewSecondsTimer(t time.Duration) *SecondsTimer {
    return &SecondsTimer{time.NewTimer(t), time.Now().Add(t)}
}

func (s *SecondsTimer) Reset(t time.Duration) {
    s.timer.Reset(t)
    s.end = time.Now().Add(t)
}

func (s *SecondsTimer) Stop() {
    s.timer.Stop()
}
Run Code Online (Sandbox Code Playgroud)

所以剩下的时间很容易:

func (s *SecondsTimer) TimeRemaining() time.Duration {
    return s.end.Sub(time.Now())
}
Run Code Online (Sandbox Code Playgroud)