英文:
How do I find the time remaining for a Timer to fire?
问题
我需要在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
}
现在我可以根据需要使用s.T.Seconds()
。
但是我担心会出现竞态条件和其他类似的问题。这样做是否可行,或者是否有更本地化的方法可以使用?
英文:
I need to run a function after x
seconds, with some ability to control (reset the timer, stop the timer, find time remaining for execution). time.Timer
is a close fit - the only thing missing is that it seems to provide no way of finding how much time is left.
What options do I have?
At the moment, I'm thinking of something like:
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
}
Now I can use s.T.Seconds()
as needed.
But I'm wary of race conditions and other such problems. Is this the way to go, or is there something more native I can use?
答案1
得分: 7
有一个更简单的方法。你仍然可以使用time.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()
}
func (s *SecondsTimer) TimeRemaining() time.Duration {
return s.end.Sub(time.Now())
}
这样,剩余时间就很容易获取了。
英文:
There is a simpler way. You can still use a time.Timer
to accomplish what you want, you just need to keep track of 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()
}
so time remaining is easy:
func (s *SecondsTimer) TimeRemaining() time.Duration {
return s.end.Sub(time.Now())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论