Pakiet time oferuje dwa przydatne narzędzia: Timer i Ticker.
Kluczowe różnice:
Timer po wyzwoleniu "wygasa", należy go zresetować (Reset), żeby użyć ponownie.Ticker generuje wydarzenia, dopóki nie zostanie jawnie zatrzymany metodą Stop().Cechy użycia:
Stop() dla Timer/Ticker po zakończeniu pracy, aby uniknąć wycieków zasobów.Stop() dla Timer, może być konieczne „osuszenie” kanału: jeśli timer wyzwolił się przed Stop(), odczyt z kanału jest obowiązkowy.Przykład poprawnego użycia Timer:
t := time.NewTimer(2 * time.Second) defer t.Stop() // obowiązkowe! select { case <-t.C: fmt.Println("Czas minął!") case <-otherDone: if !t.Stop() { <-t.C // osuszamy kanał, jeśli to konieczne } }
Czy można od razu ponownie używać Timer po otrzymaniu wartości z kanału t.C? Co się stanie, jeśli nie zrobimy t.Stop()?
Odpowiedź: Timer nie powinien być natychmiast resetowany bez wywołania Stop() i ewentualnego odczytu z kanału. Jeśli nie zrobisz t.Stop(), może pozostać "martwy" gorutyna lub niespodziewany wyzwalacz w następnym cyklu (kanał nie został oczyszczony). Poprawne użycie: wywołaj Stop(), a jeśli Stop() zwrócił false — koniecznie osusz kanał odczytem z t.C.
Historia
Historia
Ticker, który nie był zatrzymywany po zakończeniu hendlara. Handler "wisiał" nawet po usunięciu użytkownika, zużywając CPU.Historia
W testach nie wywoływano Stop() dla timera — testy zawieszały się losowo, ponieważ kanał timera nie był zwalniany, oczekiwano na drugi "ping" od timera, który nigdy nie nadchodził.