time.NewTimer不像我期望的那样工作

时间:2018-06-09 13:14:26

标签: go concurrency channel

我有一个相当简单的程序,应该在指定的持续时间后自我终止(例如,一秒钟)

代码:

package main

import (
    "fmt"
    "time"
)

func emit(wordChannel chan string, done chan bool) {
    defer close(wordChannel)

    words := []string{"The", "quick", "brown", "fox"}
    i := 0
    t := time.NewTimer(1 * time.Second)

    for {
        select {
        case wordChannel <- words[i]:
            i++
            if i == len(words) {
                i = 0
            }
        // Please ignore the following case
        case <-done:
            done <- true
            // fmt.Printf("Got done!\n")
            close(done)
            return
        case <-t.C:
            fmt.Printf("\n\nGot done!\n\n")
            return
        }
    }
}

func main() {

    mainWordChannel := make(chan string)
    // Please ignore mainDoneChannel
    mainDoneChannel := make(chan bool)

    go emit(mainWordChannel, mainDoneChannel)

    for word := range mainWordChannel {
        fmt.Printf("%s  ", word)
    }

}

我编译并执行二进制文件,你可以看到执行here

显然超过1秒。

关于NewTimer的Go文档内容为:

  

func NewTimer

     

func NewTimer(d Duration) *Timer

     

NewTimer创建一个新的Timer,它将在至少持续时间d之后在其通道上发送当前时间。

有人可以帮助我了解这里发生了什么吗?为什么程序在1秒后没有完全终止(或密切at least)?

1 个答案:

答案 0 :(得分:3)

计时器按预期工作。它向通道发送值。 我认为阅读about select statement很有用 循环中的每次迭代都可以写入通道。 如果&gt; 1通讯可以进行,不保证是哪些。 所以,如果像这样添加延迟读取循环:

String appDrawer = "Apps";
String appTitle = "<App title>";

UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.pressHome();

if (device.hasObject(By.descStartsWith(appDrawer))) {
    device.findObject(By.descStartsWith(appDrawer)).click();
}

UiScrollable apps = new UiScrollable(new UiSelector().scrollable(true));
apps.scrollForward();
apps.scrollTextIntoView(appTitle);
List<UiObject2> items = device.findObjects(By.text(appTitle));

//TODO validate items content and identify the correct index
items.get(index).click();

在这种情况下,只能从for word := range mainWordChannel { fmt.Printf("%s ", word) time.Sleep(time.Millisecond) } 读取。程序将结束。