Golang實現Time定時器超時退出方式

1. time.After

假設業務中需調用服務接口A,要求超時時間爲5秒,那麼如何優雅、簡潔的實現呢?

可以採用select+time.After的方式,十分簡單適用的實現。

package main

import (
	"fmt"
	"time"
)

//發送者
func sender(c chan int) {
	for i := 0; i < 20; i++ {
		c <- i
		if i >= 5 {
			time.Sleep(time.Second * 7)
		} else {
			time.Sleep(time.Second)
		}
	}
}

func main() {
	c := make(chan int)
	go sender(c)
	timeout := time.After(time.Second * 3)
	for {
		select {
		case d := <-c:
			fmt.Println(d)
		case <-timeout:
			fmt.Println("執行定時操作任務")
		case dd := <-time.After(time.Second * 3):
			fmt.Println(dd.Format("2006-01-02 15:04:05"), "執行超時動作")
		}
		fmt.Println("for end")
	}
}

2. time.NewTimer

NewTimer 創建一個 Timer,它會在最少過去時間段 d 後到期,向其自身的 C 字段發送當時的時間

 t.Reset()需要重置Reset 使 t 重新開始計時

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.NewTimer(time.Second * 2)
	ch := make(chan bool)
	go func(t *time.Timer) {
		defer t.Stop()
		for {
			select {
			case <-t.C:
				fmt.Println("timer running....")
				// 需要重置Reset 使 t 重新開始計時
				t.Reset(time.Second * 2)
			case stop := <-ch:
				if stop {
					fmt.Println("timer Stop")
					return
				}
			}
		}
	}(t)
	time.Sleep(10 * time.Second)
	ch <- true
	close(ch)
	time.Sleep(1 * time.Second)
}

3. time.NewTicker

NewTicker 返回一個新的 Ticker,該 Ticker 包含一個通道字段,並會每隔時間段 d 就向該通道發送當時的時間。它會調整時間間隔或者丟棄 tick 信息以適應反應慢的接收者。如果d <= 0會觸發panic。

ticker.Stop()關閉該 Ticker 可以釋放相關資源。

package main

import (
	"fmt"
	"time"
)

func main() {
	ticker := time.NewTicker(2 * time.Second) // 新建一個Ticker
	ch := make(chan bool)
	go func(ticker *time.Ticker) {
		defer ticker.Stop() // 停止Ticker
		for {
			select {
			case <-ticker.C: // Ticker.C 的封裝
				fmt.Println("Ticker running...")
			case stop := <-ch:
				if stop {
					fmt.Println("Ticker Stop")
					return
				}
			}
		}
	}(ticker)
	time.Sleep(10 * time.Second)
	ch <- true
	close(ch)
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章