选择块如何等待 ctx.Done() 操作?

在下面的代码中:


    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被封锁...


繁星淼淼
浏览 632回答 2
2回答

翻过高山走不出你

规范:选择语句:对于语句中的所有情况,在输入“select”语句时,接收操作的通道操作数以及发送语句的通道和右侧表达式仅按源顺序计算一次。select只调用ctx.Done()一次。它返回一个通道,并监视来自该通道的接收操作是否可以继续。如果超时过期,5000*time.Second或者父上下文req.Context()(不再)。规格:接收运算符:cancel()ctx.Done()关闭通道上的接收操作总是可以立即进行,在接收到任何先前发送的值之后产生元素类型的零值。

人到中年有点甜

通常,当你使用阻塞通道和超时功能时,你可以把它放在一个 for-select 循环中。ctx, cancel := context.WithTimeout(req.Context(), 5000*time.Second)&nbsp; &nbsp; // Wait for the response or timeout&nbsp; &nbsp;for {&nbsp; &nbsp; select {&nbsp; &nbsp; case <-ctx.Done():&nbsp; &nbsp; &nbsp; &nbsp; log.Println("timeout, cancel work...")&nbsp; &nbsp; &nbsp; &nbsp; // Cancel the request and wait for it to complete&nbsp; &nbsp; &nbsp; &nbsp; // this will shutdown the go-routine immediately&nbsp; &nbsp; &nbsp; &nbsp; tr.CancelRequest(req)&nbsp; &nbsp; &nbsp; &nbsp; log.Println(<-ch)&nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; case err := <-ch:&nbsp; &nbsp; &nbsp; &nbsp; // do something&nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; }&nbsp; &nbsp;}在这种情况下,<-ch不再阻塞,并且 select 调用ctx.Done()不止一次。如果您不使用 for 循环,ctx.Done()则只调用一次(正如@icza 已经指出的那样)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go