package main
import (
"context"
"fmt"
"log"
"time"
)
func complexBusinessLogic(ctx context.Context) error {
// 模拟从数据库读取数据并处理
fmt.Println("开始执行复杂业务逻辑")
time.Sleep(2 * time.Second)
fmt.Println("复杂业务逻辑执行完毕")
// 这里简单返回nil表示无错误,实际中根据业务处理返回具体错误
return nil
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go func() {
for {
select {
case <-ctx.Done():
return
default:
err := complexBusinessLogic(ctx)
if err != nil {
log.Printf("执行复杂业务逻辑出错: %v", err)
}
time.Sleep(2 * time.Second)
}
time.Sleep(3 * time.Second)
}
}()
// 模拟运行10秒后停止任务
time.Sleep(10 * time.Second)
cancel()
fmt.Println("定时任务已停止")
}
错误处理
- 业务逻辑错误:在
complexBusinessLogic
函数中,实际的数据库读取和处理操作可能会返回错误。在示例代码中,complexBusinessLogic
简单返回nil
,实际应用中应根据具体的数据库操作返回相应的错误。在调用complexBusinessLogic
的地方,通过if err != nil
判断并使用log.Printf
记录错误信息,这样可以方便调试和排查问题。
- 其他潜在错误:如
context
相关操作可能出现的错误,由于context.WithCancel
操作通常不会失败,所以这里不需要额外处理其错误。但如果是使用context.WithTimeout
等操作,可能需要处理context
创建时返回的错误。
安全停止定时任务
- 使用
context
:通过context.WithCancel
创建一个可取消的context
,并传递给complexBusinessLogic
函数和select
语句中的ctx.Done()
通道。当调用cancel()
函数时,ctx.Done()
通道会收到信号,从而跳出for
循环,安全停止定时任务。
- 避免资源泄露:在
complexBusinessLogic
函数内部,如果涉及到数据库连接等资源,应确保在函数返回时正确关闭资源,避免资源泄露。在示例代码中虽然是模拟的业务逻辑,但实际应用中要特别注意这一点。