英文:
What is better to use for running function after some time?
问题
什么更好使用?time.AfterFunc 还是带有 sleep 的 goroutine?
time.AfterFunc(d, func() {
// 事情
})
go func() {
time.Sleep(d)
// 事情
}()
这两种方法都可以实现在一定时间后执行某些操作。它们的选择取决于具体的需求和场景。
-
如果你只需要在指定时间后执行一次操作,并且不需要取消或重置定时器,那么使用
time.AfterFunc
是一个简单且方便的选择。它会在指定的时间过后调用提供的函数。 -
如果你需要在指定时间后执行操作,并且可能需要在执行之前取消或重置定时器,那么使用带有 sleep 的 goroutine 是更灵活的选择。你可以使用
time.Sleep
来暂停 goroutine 的执行,然后在指定的时间过后执行操作。
总的来说,如果你只需要简单地在指定时间后执行操作,而不需要取消或重置定时器,那么 time.AfterFunc
是更直观和方便的选择。如果你需要更多的灵活性和控制权,可以使用带有 sleep 的 goroutine。
英文:
What is better to use? time.AfterFunc or goroutine with sleep?
time.AfterFunc(d, func() {
// things
})
go func() {
time.Sleep(d)
// things
}()
答案1
得分: 3
大多数计算机科学问题都取决于使用情况。你的两个选择都会创建一个goroutine。话虽如此,我会避免使用time.Sleep()
,因为它是不可中断的。
看一个假设的轮询服务示例:
func poller(ctx context.Context) (err error) {
for {
if err = pollRecords(ctx); err != nil {
return
}
time.Sleep(1*time.Hour) // <- 轮询间隔无法中断
}
}
即使上下文已被取消,这个函数可能会运行长达一小时,因为time.Sleep
是不可中断的。
为了修复这个问题,可以使用基于通道的time.After()
:
// time.Sleep(1*time.Hour)
select {
case <-ctx.Done():
return ctx.Err() // 取消上下文会中断time.After
case <-time.After(1*time.Hour):
}
注意:time.AfterFunc可以被取消,但需要捕获返回的time.Timer
:
t := time.AfterFunc(d, func() {
// 做一些事情
})
// ...
t.Stop() // 如果决定停止函数触发,可以调用该方法
英文:
Like most computer science questions - the answer depends on the usage. Both your choices will create a goroutine. Having said that, I'd avoid time.Sleep()
as it's uninterruptible.
Looking at a contrived polling service example:
func poller(ctx context.Context) (err error) {
for {
if err = pollRecords(ctx); err != nil {
return
}
time.Sleep(1*time.Hour) // <- poll interval cannot be interrupted
}
}
this function may be running for up to an hour, even after the context has been canceled, because of the uninterruptible nature of time.Sleep
.
To fix, one can use the channel based time.After()
:
// time.Sleep(1*time.Hour)
select {
case <-ctx.Done():
return ctx.Err() // cancelling the context interrupts the time.After
case <-time.After(1*time.Hour):
}
Note time.AfterFunc can be canceled - but you need to capture the returned time.TImer
:
t := time.AfterFunc(d, func() {
// things
})
// ...
t.Stop() // will stop the function firing - if one decides to do so
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论