gpt4 book ai didi

go - 使用 time.AfterFunc 在 golang 中按时间间隔执行重复性任务,只是一个示例

转载 作者:数据小太阳 更新时间:2023-10-29 03:06:10 25 4
gpt4 key购买 nike

我只想在 Go 中做重复的后台任务,使用 time.AfterFunc,但似乎逻辑有问题。输出只是:间隔调用间隔调用

但如果一切正常,至少要调用该函数 5 次。

package main

import (
"fmt"
"time"
"os"
"os/signal"
)

type Timer struct {
Queue chan *TimeCall
}

func NewTimer(l int) *Timer {
timer := new(Timer)
timer.Queue = make(chan *TimeCall,l)
return timer
}

type TimeCall struct {
timer *time.Timer
callback func()
}

func (this *TimeCall) CallBack() {
defer func() { recover() }()
if this.callback != nil {
this.callback()
}
}

func (this *Timer) AfterFunc(d time.Duration, callback func()) *TimeCall {
call := new(TimeCall)
call.callback = callback
call.timer = time.AfterFunc(d, func() {
this.Queue <- call
})
return call
}



type PipeService struct {
TimeCall *Timer
}

func (this *PipeService) AfterFunc(delay time.Duration, callback func()) *TimeCall {
return this.TimeCall.AfterFunc(delay, callback)
}

func (this *PipeService) IntervalCall(interval time.Duration, callback func()) {
this.TimeCall.AfterFunc(interval,func(){
if callback != nil {
callback()
}
this.AfterFunc(interval,callback)
})
}

func (this *PipeService) Run(closeSig chan bool) {
for {
select {
case <-closeSig:
return
case call := <-this.TimeCall.Queue:
call.CallBack()
}
}
}

func main() {
var closeChan chan bool
InsPipeService := &PipeService{TimeCall: NewTimer(10)}
InsPipeService.IntervalCall(2*time.Second,func(){
fmt.Println("interval call")
})

c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill)

go func(){
InsPipeService.Run(closeChan)
}()

time.Sleep(10*time.Second)
}

Run Code

最佳答案

time.AfterFunc()返回 *time.Timer ,引用其文档:

The Timer type represents a single event. When the Timer expires, the current time will be sent on C, unless the Timer was created by AfterFunc.

time.AfterFunc() 返回的time.Timer 不会重复,所以您看到的是完全正常的:在您的 PipeService.IntervalCall() 立即执行回调,它会在超时后执行。

另请注意,您将 2 作为 PipeService.IntervalCall() 方法的间隔传递。此 interval 参数的类型为 time.Duraion .因此,当您传递 2 时,这不会是 2 秒(但实际上是 2 纳秒)。您应该传递一个由 time 包中的常量构造的值,例如:

InsPipeService.IntervalCall(2 * time.Second, func(){
fmt.Println("interval call")
})

如果你想重复,使用time.Ticker .例如,以下代码每 2 秒打印一条消息:

t := time.NewTicker(2 * time.Second)
for now := range t.C {
fmt.Println("tick", now)
}

或者如果您不需要 Ticker 并且不想将其关闭:

c := time.Tick(2 * time.Second)
for now := range c {
fmt.Println("tick", now)
}

关于go - 使用 time.AfterFunc 在 golang 中按时间间隔执行重复性任务,只是一个示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36886548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com