为了账号安全,请及时绑定邮箱和手机立即绑定

在 go 中重用带有 context.WithTimeout 的父上下文?

在 go 中重用带有 context.WithTimeout 的父上下文?

Go
慕桂英4014372 2022-06-01 09:55:07
使用带有新超时的 context.WithTimeout 重用父上下文你好,我是新来的go。我想知道是否可以重用父上下文来创建多个 context.withTimeout()。基本原理是我必须按顺序调用多个网络请求,并希望使用父上下文同时为每个请求设置超时。基本原理当父上下文被取消时,所有发出的请求也将被取消。问题在下面的代码中,它显示了一个示例,LongProcess即网络请求。LongProcess但是,在可以使用 进行第二次调用之前,上下文已关闭context deadline exceeded。该文件withDeadline指出The returned context's Done channel is closed when the deadline expires, when the returned cancel function is called, or when the parent context's Done channel isclosed, whichever happens first.因此,如果是这种情况,有没有办法可以重置 withTimeout 的计时器?还是我必须context.Background()为每个请求创建一个新的上下文?这意味着不会传递父上下文。:(// LongProcess refers to a long network requestfunc LongProcess(ctx context.Context, duration time.Duration, msg string) error {    c1 := make(chan string, 1)    go func() {        // Simulate processing        time.Sleep(duration)        c1 <- msg    }()    select {    case m := <-c1:        fmt.Println(m)        return nil    case <-ctx.Done():        return ctx.Err()    }}func main() {    ctx := context.Background()    t := 2 * time.Second    ctx, cancel := context.WithTimeout(ctx, t)    defer cancel()    // Simulate a 2 second process time    err := LongProcess(ctx, 2*time.Second, "first process")    fmt.Println(err)    // Reusing the context.    s, cancel := context.WithTimeout(ctx, t)    defer cancel()    // Simulate a 1 second process time    err = LongProcess(s, 1*time.Second, "second process")    fmt.Println(err) // context deadline exceeded}
查看完整描述

1 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

它看起来像是第一次调用context.WithTimeout隐藏父上下文ctx。后面的过程会重新使用这个已经取消的上下文,因此会出现错误。您必须重新使用父级。这是更新的示例:


func main() {

    // Avoid to shadow child contexts

    parent := context.Background()

    t := 2 * time.Second


    // Use the parent context.

    ctx1, cancel := context.WithTimeout(parent, t)

    defer cancel()


    err := LongProcess(ctx1, 2*time.Second, "first process")

    fmt.Println(err)


    // Use the parent context not the canceled one.

    ctx2, cancel := context.WithTimeout(parent, t)

    defer cancel()


    err = LongProcess(ctx2, 1*time.Second, "second process")

    fmt.Println(err)

}


查看完整回答
反对 回复 2022-06-01
  • 1 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信