在下面的代码中: ctx, cancel := context.WithTimeout(req.Context(), 5000*time.Second) // Wait for the response or timeout select { case <-ctx.Done(): log.Println("timeout, cancel work...") // Cancel the request and wait for it to complete // this will shutdown the go-routine immediately tr.CancelRequest(req) log.Println(<-ch) case err := <-ch: // do something }select同时等待两个接收操作。一个接收操作(<-ch)是一个块操作在块的执行中select,是否ctx.Done()在块中多次调用select以验证是否ctx.Done()返回通道?直到<-ch被封锁...
2 回答
人到中年有点甜
TA贡献1895条经验 获得超7个赞
通常,当你使用阻塞通道和超时功能时,你可以把它放在一个 for-select 循环中。
ctx, cancel := context.WithTimeout(req.Context(), 5000*time.Second)
// Wait for the response or timeout
for {
select {
case <-ctx.Done():
log.Println("timeout, cancel work...")
// Cancel the request and wait for it to complete
// this will shutdown the go-routine immediately
tr.CancelRequest(req)
log.Println(<-ch)
break
case err := <-ch:
// do something
break
}
}
在这种情况下,<-ch不再阻塞,并且 select 调用ctx.Done()不止一次。如果您不使用 for 循环,ctx.Done()则只调用一次(正如@icza 已经指出的那样)
- 2 回答
- 0 关注
- 631 浏览
添加回答
举报
0/150
提交
取消