Timeout与Context canceled Error的区别:求详细解答及示例
Timeout 与 Context Canceled Error 的区别
核心触发差异
- Timeout Error:上下文预设了超时时间,时间到点后自动触发取消,属于被动超时终止。
- Context Canceled Error:通过手动调用
cancel()函数触发,或是父上下文被取消时传递的取消信号导致,属于主动触发的终止。
错误标识(以Go语言为例)
在Go的context包中,两者对应明确的错误常量:
- Timeout错误对应
context.DeadlineExceeded - Canceled错误对应
context.Canceled
示例1:Timeout Error 场景
当任务执行时间超过上下文设置的超时时间时,会触发Timeout错误:
package main import ( "context" "fmt" "time" ) func main() { // 创建一个2秒后超时的上下文 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() // 确保上下文资源被正确释放 // 模拟一个需要3秒才能完成的任务 go func() { time.Sleep(3 * time.Second) fmt.Println("任务完成") }() // 等待上下文状态变更 <-ctx.Done() // 检查错误类型 if err := ctx.Err(); err != nil { switch err { case context.DeadlineExceeded: fmt.Println("触发Timeout错误:", err) case context.Canceled: fmt.Println("触发Canceled错误:", err) } } }
运行结果:
触发Timeout错误: context deadline exceeded
任务还没执行完,上下文就因超时自动取消。
示例2:手动触发 Context Canceled Error
主动调用cancel()函数终止上下文,触发Canceled错误:
package main import ( "context" "fmt" "time" ) func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // 模拟一个持续运行的任务 go func() { for { select { case <-ctx.Done(): fmt.Println("任务收到取消信号,停止运行") return default: fmt.Println("任务正在运行...") time.Sleep(500 * time.Millisecond) } } }() // 2秒后手动取消上下文 time.Sleep(2 * time.Second) cancel() // 等待任务退出 time.Sleep(1 * time.Second) if err := ctx.Err(); err == context.Canceled { fmt.Println("触发Canceled错误:", err) } }
运行结果:
任务正在运行... 任务正在运行... 任务正在运行... 任务正在运行... 任务收到取消信号,停止运行 触发Canceled错误: context canceled
示例3:父上下文取消导致子上下文触发Canceled Error
上下文具有层级关系,父上下文被取消时,所有子上下文都会收到取消信号:
package main import ( "context" "fmt" "time" ) func main() { parentCtx, parentCancel := context.WithCancel(context.Background()) // 基于父上下文创建子上下文 childCtx, _ := context.WithCancel(parentCtx) // 监听子上下文的状态 go func(ctx context.Context) { <-ctx.Done() if err := ctx.Err(); err == context.Canceled { fmt.Println("子上下文触发Canceled错误:", err) } }(childCtx) // 1秒后取消父上下文 time.Sleep(1 * time.Second) parentCancel() // 等待子上下文处理完成 time.Sleep(500 * time.Millisecond) }
运行结果:
子上下文触发Canceled错误: context canceled
总结
| 维度 | Timeout Error | Context Canceled Error |
|---|---|---|
| 触发方式 | 时间到期自动触发 | 手动调用/父上下文传递取消信号 |
| Go错误常量 | context.DeadlineExceeded | context.Canceled |
| 典型场景 | 限制任务最长执行时间 | 用户取消请求、服务关闭清理资源 |
内容的提问来源于stack exchange,提问作者Gaurav Jain
相关产品推荐
相关产品推荐

