我无法理解如何检查上下文是否超出了超时设置的期限,或者我是否应该进行检查?
这是mongo-go-driver的片段:
client, err := NewClient("mongodb://foo:bar@localhost:27017")
if err != nil { return err }
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil { return err }
阅读此代码,我如何知道上下文是否超过了期限?根据我天真的理解(或不理解),行err = client.Connect(ctx)
会给我错误,包括超过了截止日期(如果超过了),因此我认为我什至不需要显式检查?
但是随后环顾互联网以更好地了解上下文如何工作时,我遇到了一些选择情况的用法,这些情况明确地检查了以下情况(http://p.agnihotry.com/post/understanding_the_context_package_in_golang/的代码段):
//Use a select statement to exit out if context expires
select {
case <-ctx.Done():
fmt.Println("sleepRandomContext: Time to return")
case sleeptime := <-sleeptimeChan:
//This case is selected when processing finishes before the context is cancelled
fmt.Println("Slept for ", sleeptime, "ms")
}
我应该明确检查吗?如果没有,我什么时候应该使用显式检查?谢谢您的时间和帮助!
答案 0 :(得分:2)
问题第二部分中的select
代码是Connect
方法中的代码。那里正在检查ctx.Done()
是否已准备好发送。如果是,则由于发生超时或调用了cancel()
而取消了上下文。
答案 1 :(得分:1)
context
最适合用来管理事物的生命周期。因此,如果您正在执行某些操作(例如,处理文件),则应检查上下文,以确保未处理该过程。
有两种检查context
是否已取消或超时的方法:
Context.Done()
-返回取消关联时将关闭的通道。Context.Err()
-如果取消了上下文,这将返回错误。选择最适合您的需求。如果您正在处理通道,则在context.Done()
中使用select
会很好。如果您在读取for
时使用io.Reader
循环,那么检查context.Err()
会更容易。
总而言之,如果您要开始的事情也需要上下文,那么如果希望取消该新的“事物”,则应该始终使用已有的上下文。