我寫了以下函式:
func (timer *Timer) ticker() {
for timer.time >= 0 {
select {
case <-timer.stopFlag:
return
default:
timer.DataChannel <- timer.timeToString()
timer.time--
time.Sleep(time.Second)
}
}
}
func startLabelUpdateListener(timer *t.Timer, w *app.Window, label *string) {
for time := range timer.DataChannel {
*label = time
w.Invalidate()
}
}
這是一個簡單的計時器,它連接到一個標簽,每當 DataChanel 上有更新時,該標簽就會更新。它們都被稱為 goroutines。
現在有沒有辦法立即停止自動收報機并再次呼叫它,就在之后?假設我想重新啟動這個計時器。我希望它立即停止,并啟動另一個ticker goroutine 來接管。
我嘗試了以下方法,但遇到了一些問題:
timer.stopFlag <- true
go timer.ticker()
...
這樣做的問題是它不是即時的,因為我正在使用 time.Sleep() go 等到睡眠結束,這對于回應性來說并不是很好,因為這會引入 UI 延遲。手動更新標簽dataChannel <- "some_time"意味著如果用戶在 0.9 秒睡眠后單擊重新啟動按鈕,則計時器在 1.9 秒內不會改變。
close(timer.stopFlag)
timer.stopFlag = make(chan bool)
go timer.ticker()
...
這很好而且即時(通過睡眠或至少看起來是這樣)但問題是,通道現在已關閉并重新打開它以某種方式阻止前一個 goroutine 終止并按下重新啟動按鈕幾次堆疊 goroutine
我還考慮過將 time.sleep 設定為 0.1 秒,并且每 10 次迭代減少一次時間,但這感覺有點笨拙。有更好的解決方案嗎?
uj5u.com熱心網友回復:
使用 time.Ticker而不是睡覺。
func (timer *Timer) ticker() {
// Send the first.
timer.DataChannel <- timer.timeToString()
timer.time--
// Loop sending each second.
t := time.NewTicker(time.Second)
defer t.Stop()
for timer.time >= 0 {
select {
case <-timer.stopFlag:
return
case <-t.C:
timer.DataChannel <- timer.timeToString()
timer.time--
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/414537.html
標籤:
