我目前有这个代码试图计算触发某个条件所用的时间。 (伪):
timeDelay = 900000 // time.Microsecond
for {
// if a certain something happens, start a counting (time)
if (certainSomething) {
startTime = time.Now();
if !prevTime.IsZero() {
// add the time elapsed time to timeTick
diffTime = time.Since(prevTime)
timeTick = timeTick + diffTime
}
prevTime = startTime
}
if (timeTick < timeDelay) { // lessThan()
// still has not reached target count (time elapsed)
fmt.Println("Not Yet")
// we dont want to get to the end of the loop yet
continue
}
if (timeTick > timeDelay) { // greaterThan()
// has finally reached the target count (time elapsed)
fmt.Println("Yes! Finally")
// yes the delay has been reached lets reset the time
// and if `thisHappened` is triggered again, lets start counting again
timeTick = time.Duration(0 * time.Microsecond)
}
// function shouldn't be called if the elapsed amount
// of time required has not yet been reached
iShouldOnlyBeCalledWhenDelayHasBeenReached();
}
我也将它们用作辅助函数(实际代码)
func lessThan(diff time.Duration, upper int) bool {
return diff < time.Duration(upper)*time.Microsecond && diff != 0
}
func greaterThan(diff time.Duration, upper int) bool {
return diff > time.Duration(upper)*time.Microsecond
}
但是,我对自己的表现并不满意。我不应该算数,对吗?我应该倒计时......我只是感到困惑,需要帮助我应该采用什么方法。
我想要发生什么:
1.当timeDelay
发生时,certainSomething
到0的倒计时开始
2.在倒计时到达0之前,请勿致电iShouldOnlyBeCalledWhenDelayHasBeenReached
这应该都发生在一个循环中,一个服务器循环准确地接收数据包。
我的问题:
1.我应该怎么做以实现倒计时风格?
谢谢,任何建议或示例代码都会有很大帮助。
注意:循环中还有其他功能。做其他事情。这是主循环。我无法做到
Sleep
。
答案 0 :(得分:2)
您可以设置频道,以便在您超出时间时通知您。
以下是on play
的示例它有一个额外的好处,在select语句中,您可以将其他通道用于其他目的。例如,如果你在这个循环中做其他工作,你也可以在goroutine中产生那个工作并让它将结果发送回另一个通道。
然后在timeDelay
之后或其他工作完成时退出,或者其他任何内容。
package main
import (
"fmt"
"time"
)
func main() {
certainSomething := true // will cause time loop to repeat
timeDelay := 900 * time.Millisecond // == 900000 * time.Microsecond
var endTime <-chan time.Time // signal for when timer us up
for {
// if a certain something happens, start a timer
if certainSomething && endTime == nil {
endTime = time.After(timeDelay)
}
select {
case <-endTime:
fmt.Println("Yes Finally!")
endTime = nil
default:
fmt.Println("not yet")
time.Sleep(50 * time.Millisecond) // simulate work
continue
}
// function shouldn't be called if the elapsed amount
// of time required has not yet been reached
iShouldOnlyBeCalledWhenDelayHasBeenReached() // this could also just be moved to the <- endtime block above
}
}
func iShouldOnlyBeCalledWhenDelayHasBeenReached() {
fmt.Println("I've been called")
}
答案 1 :(得分:2)
因为这是一个你说的游戏,所以你听起来像是:
delay
金额,请停止工作并重新循环如果是这种情况,那么您有一些选项和模式。
想到了{p> time.After。我喜欢select语句中time.After
的清洁度。没有渠道或goroutines需要处理它。
此模式还具有使用goroutine作为主游戏逻辑的额外好处。
在游戏中:http://play.golang.org/p/FIiUJ0CHZz
更改time.After()
以查看其实际效果。
func main() {
for {
// creating a new channel on each loop will allow the
// GC to collect any game stuff that completes after the timeout.
done := make(chan int)
// main game func, doing your other stuff.
// since this is in a goroutine, it won't block
// and we can check the state in the select.
go func(){
// complicated logic here!
//
// you must issue an "I am done!"
done <- 1
}()
// this will block the for loop until a timeout occurs
select {
case <- done:
continue
case <- time.After(1000 * time.Nanosecond):
iShouldOnlyBeCalledWhenDelayHasBeenReached()
}
}
}
答案 2 :(得分:1)
如果您无法进行常规睡眠,则应使用time.Time.Add
和time.Time.After
(或time.Time.Before
)功能。
沿着这些线路的东西
package main
import "time"
func main() {
var d = 1000 * time.Microsecond
var t = time.Now().Add(d)
for {
if time.Now().Before(t) {
continue
}
do_something()
}
}
或者在您可以睡觉的例行程序中将您必须在一段时间后运行的方法逐出:
package main
import "time"
func main() {
var d = 1000 * time.Microsecond
go func() {
time.Sleep(d)
do_something()
}()
}
答案 3 :(得分:0)
我认为这可以解决您的问题。
package main
import (
"fmt"
"time"
)
func main() {
time.Sleep(2 * time.Second)
fmt.Println("Time is up!")
}