After time with time.After的行为不像是用代码或计时器超时

I expect the follwoing to functions to behave the same way

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
        }
    }
}

calling them as :

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

prints:

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

i thought that they would behave exactly the same way and i really don't get the huge difference, any thoughts on this?

note also using a timer works as expected like in the ticker function.

The problem lies within your code.

In your first example, you are creating one ticker and use that for timing out.
In your second example, you create a timer every time you loop:

case <-time.After(maxDuration):

As can be seen in the library sources, this is equivalent to

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

If you create a new Ticker/Timer every time you loop (and discard the old one), it will probably never fire.

So, to get your second example to behave correctly, do it like this (untested):

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
        }
    }
}