loops - 停止 time.NewTimer 在 for 循环中初始化
问题描述
我有一个类似于以下程序的程序:
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan string)
go endProgram(ch)
printFunc(ch)
}
func printFunc(ch chan string) {
for {
timeout := time.NewTimer(getTimeoutDuration())
defer timeout.Stop()
select {
case s := <-ch:
fmt.Println(s)
return
case <-timeout.C:
fmt.Println("Current value")
}
}
}
func endProgram(ch chan string) {
time.Sleep(time.Second * 8)
ch <- "Exit function"
}
func getTimeoutDuration() time.Duration {
return time.Second * 3
}
在这种情况下停止timeout
计时器的最佳方法是什么?
我知道上面不是推荐的方法,因为在 for 循环中使用 defer 是一种不好的做法。另一种方法是time.After
在 for 循环中使用,而不是time.NewTimer
因为我们不必 stop time.After
。但是如果函数在计时器触发( Sourcetime.After
)之前退出,则会导致资源泄漏。
解决方案
如果您使用上下文而不是计时器,则仅在退出函数案例条件时才调用取消。
package main
import (
"context"
"fmt"
"time"
)
func main() {
ch := make(chan string)
go endProgram(ch)
printFunc(ch)
}
func printFunc(ch chan string) {
for {
ctx, cancel := context.WithTimeout(context.Background(), getTimeoutDuration())
select {
case s := <-ch:
cancel()
fmt.Println(s)
return
case <-ctx.Done():
fmt.Println("Current value")
}
}
}
func endProgram(ch chan string) {
time.Sleep(time.Second * 8)
ch <- "Exit function"
}
func getTimeoutDuration() time.Duration {
return time.Second * 3
}
推荐阅读
- python - 在循环中的每个字符后插入句点
- macos - 为什么 macOS 文件系统观察器比 Linux 慢并且在 WebStorm 中不起作用?
- datetime - sql-server 2019 中的 Getdate() 给出错误的日期
- javascript - 应用 [hide] 和 [show] TOC 按钮时出现放大器错误
- sql - 创建单个月度值时出现错误的案例
- android - React Native 通知徽章图标与 Android 中的计数
- css - 使用 css 在标签内添加 data-aos
- assembly - 为什么我在 movaps 指令上使用不稳定的裸汇编功能会出现段错误?
- python - 实时从 django 获取数据到 React
- javascript - 删除数组中键周围的双引号