1 回答
TA贡献1815条经验 获得超6个赞
context.Context只能中继发生超时或取消的消息。它无权实际停止任何 goroutines(有关详细信息,请参阅取消 Go 中的阻塞操作)。goroutine 本身负责检查超时和取消,并提前中止。
你有一个循环,它无条件地迭代 10 次并打印一些东西。而且您只在循环后检查超时。
您必须将上下文检查移动到循环中:
func F(ctx context.Context) error {
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
for i := 0; i < 10; i++ {
select {
case <-ctx.Done():
fmt.Println("TIME OUT")
return ctx.Err()
default:
time.Sleep(1 * time.Second)
fmt.Println("No: ", i)
}
}
fmt.Println("ALL DONE")
return nil
}
通过此更改,输出将是(在Go Playground上尝试):
No: 0
No: 1
No: 2
No: 3
TIME OUT
context deadline exceeded
注意:无论您看到"No: 3"打印可能会或可能不会发生,因为任何迭代都需要 1 秒,并且超时是 3 秒 = 3 * 迭代延迟,所以是先发生超时还是第 4 次迭代首先开始是“活泼的”。如果将超时时间减少到 2900 毫秒,"No: 3"则不会打印。
- 1 回答
- 0 关注
- 637 浏览
添加回答
举报
