time.Ticker în Go

Un ceas care trimite câte o valoare pe canalul C la fiecare interval; Stop îl oprește, Reset îi schimbă intervalul.

Sintaxă
type Ticker struct {
    C <-chan Time
}

func NewTicker(d Duration) *Ticker
func (t *Ticker) Stop()
func (t *Ticker) Reset(d Duration)   // Go 1.15

Ce face time.Ticker

time.NewTicker(d) creează un obiect care „bate” la fiecare d: pe canalul t.C sosește câte o valoare. Este potrivit pentru sarcini periodice: salvare automată, trimiterea de statistici, verificarea unei cozi.

t.Stop() oprește bătăile (canalul nu se închide, doar nu mai primește nimic). t.Reset(d) schimbă intervalul; următoarea bătaie vine după noul interval. d trebuie să fie mai mare decât zero, altfel NewTicker și Reset se opresc cu panică.

Dacă nu ai nevoie de Stop sau Reset, time.Tick(d) este mai scurt.

Ce returnează

NewTicker: *time.Ticker. Stop și Reset nu returnează nimic.

Exemple

Exemplul 1: Bătăi la interval, apoi Stop

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.NewTicker(80 * time.Millisecond)

	for i := 1; i <= 3; i++ {
		<-t.C
		fmt.Println("Trimit statisticile, runda", i)
	}
	t.Stop()
	fmt.Println("Ticker oprit")
}

Rezultat

Trimit statisticile, runda 1
Trimit statisticile, runda 2
Trimit statisticile, runda 3
Ticker oprit

Exemplul 2: Reset: încetinește când nu e de lucru

Verificăm coada des, iar când se golește mărim intervalul cu Reset.

package main

import (
	"fmt"
	"time"
)

func main() {
	coada := []string{"comanda 101", "comanda 102"}
	interval := 30 * time.Millisecond
	t := time.NewTicker(interval)
	defer t.Stop()

	for runda := 1; runda <= 4; runda++ {
		<-t.C
		if len(coada) > 0 {
			fmt.Println("Procesez", coada[0])
			coada = coada[1:]
			continue
		}
		if interval < 100*time.Millisecond {
			interval = 100 * time.Millisecond
			t.Reset(interval)
			fmt.Println("Coada e goală, verific mai rar:", interval)
		} else {
			fmt.Println("Tot nimic")
		}
	}
}

Rezultat

Procesez comanda 101
Procesez comanda 102
Coada e goală, verific mai rar: 100ms
Tot nimic

Greșeli frecvente

  • Așteptăți ca după Stop bucla for range t.C să se termine. Canalul nu se închide, deci bucla se blochează; ieși cu return, break sau un select cu un canal de oprire.
  • Dai lui NewTicker o durată 0 (de exemplu citită greșit din configurare): programul se oprește cu panică.

Comenzi înrudite

  • time.Tick: Returnează un canal care primește o valoare la fiecare interval d, la nesfârșit; bun pentru sarcini repetate.
  • time.Timer: Un temporizator care trimite un singur semnal pe canalul C după o durată; poate fi oprit (Stop) sau repornit (Reset).
  • time.After: Returnează un canal care primește ora curentă după durata dată; folosit în select pentru limite de timp (timeout).