随着时间的推移而超时。之后的行为不像是使用自动收报机或计时器进行超时

时间:2015-09-19 12:33:53

标签: go

我希望以下功能的行为方式相同

func fillChanTimeoutUsingTicker(maxDuration time.Duration, chanSize int) chan string {
    c := make(chan string, chanSize)
    ticker := time.NewTicker(maxDuration)
    for {
        select {
        case <-ticker.C:
            ticker.Stop()
            fmt.Println("Ticker:operation timedout")
            return c
        case c <- "Random message":
        default:
            fmt.Println("Ticker:chan is full")
            return c
        }
    }
}

func fillChanTimeoutUsingTimeAfter(maxDuration time.Duration, chanSize int) chan string {
    c := make(chan string, chanSize)
    for {
        select {
        case <-time.After(maxDuration):
            fmt.Println("time.After:operation timedout")
            return c
        case c <- "Random message":
        default:
            fmt.Println("time.After:chan is full")
            return c
        }
    }
}

将其称为:

    resWithTicker := fillChanTimeoutUsingTicker(time.Duration(1*time.Microsecond), 10000000)
    fmt.Println(len(resWithTicker))
    resWithTimeAfter := fillChanTimeoutUsingTimeAfter(time.Duration(1*time.Microsecond), 10000000)
    fmt.Println(len(resWithTimeAfter))

打印:

Ticker:operation timedout
43979
time.After:chan is full
10000000

我认为他们会表现得完全一样,我真的没有得到巨大的差异,对此有何看法?

请注意,使用计时器的工作方式与预期功能一样正常。

1 个答案:

答案 0 :(得分:3)

问题在于您的代码。

在您的第一个示例中,您正在创建一个代码,并将其用于超时 在第二个示例中,每次循环时都会创建一个计时器

case <-time.After(maxDuration):

library sources可以看出,这相当于

case <- time.NewTimer(maxDuration).C:

如果你每次循环创建一个新的Ticker / Timer(并丢弃旧的Ticker / Timer),它可能永远不会触发。

所以,为了让你的第二个例子表现得正确,就这样做(未经测试):

func fillChanTimeoutUsingTimeAfter(maxDuration time.Duration, chanSize int) chan string {
    c := make(chan string, chanSize)
    t := time.After(maxDuration)
    for {
        select {
        case <-t:
            fmt.Println("time.After:operation timedout")
            return c
        case c <- "Random message":
        default:
            fmt.Println("time.After:chan is full")
            return c
        }
    }
}