英文:
continue the execution of a function after handled panic
问题
我正在尝试创建一个任务调度程序,可以在给定的时间间隔内执行任务,并且可以处理发生的 panic。我的问题是,在处理 panic 后如何继续执行函数。
func scheduleTask(task func() error, interval time.Duration, timeout time.Duration) {
// 添加 WaitGroup 和 Mutex
var wg sync.WaitGroup
var mtx sync.Mutex
var startTime = time.Now()
// 将每个任务添加到一个 goroutine 中,并为函数设置间隔和超时时间
wg.Add(1)
go func() {
defer wg.Done()
for {
// 检查时间是否到期
if time.Since(startTime) > timeout {
break
}
defer func() {
if r := recover(); r != nil {
log.Println("Recovering from panic:", r)
}
}()
mtx.Lock()
task()
mtx.Unlock()
}
}()
wg.Wait()
}
func main() {
var a = 0
scheduleTask(func() error {
time.Sleep(50 * time.Millisecond)
if a == 3 {
a++
panic("oops")
}
a++
return nil
}, time.Millisecond*100, time.Millisecond*1000)
log.Println(a)
if a != 10 {
log.Fatal("Expected it to be 10")
}
}
以上是你提供的代码的翻译。
英文:
I'm trying to make a task scheduler that does tasks in the given interval and also can handle an occurring panic. My question is how can I continue executing the function after handling the panic.
func scheduleTask(task func() error, interval time.Duration, timeout time.Duration) {
//add waitgroup and mutex
var wg sync.WaitGroup
var mtx sync.Mutex
var startTime = time.Now()
//add each task to a goroutine and set interval and timeout to the function
wg.Add(1)
go func() {
defer wg.Done()
for {
//check if the time is up
if time.Since(startTime) > timeout {
break
}
defer func() {
if r := recover(); r != nil {
log.Println("Recovering from panic:", r)
}
}()
mtx.Lock()
task()
mtx.Unlock()
}
}()
wg.Wait()
}
func main() {
var a = 0
scheduleTask(func() error {
time.Sleep(50 * time.Millisecond)
if a == 3 {
a++
panic("oops")
}
a++
return nil
}, time.Millisecond*100, time.Millisecond*1000)
log.Println(a)
if a != 10 {
log.Fatal("Expected it to be 10")
}
}
答案1
得分: 1
当恢复时,您将退出当前函数。在这种情况下,您可以轻松地将task()
包装在闭包中。
package main
import (
"log"
"sync"
"time"
)
func scheduleTask(task func() error, interval time.Duration, timeout time.Duration) {
// 添加 waitgroup 和 mutex
var wg sync.WaitGroup
var mtx sync.Mutex
var startTime = time.Now()
// 将每个任务添加到 goroutine 中,并为函数设置间隔和超时
wg.Add(1)
go func() {
defer wg.Done()
for {
// 检查时间是否到期
if time.Since(startTime) > timeout {
break
}
mtx.Lock()
func() {
defer func() {
if r := recover(); r != nil {
log.Println("从 panic 中恢复:", r)
}
}()
task()
}()
mtx.Unlock()
}
}()
wg.Wait()
}
func main() {
var a = 0
scheduleTask(func() error {
time.Sleep(50 * time.Millisecond)
if a == 3 {
a++
panic("糟糕")
}
a++
return nil
}, time.Millisecond*100, time.Millisecond*1000)
log.Println(a)
if a != 10 {
log.Fatal("期望值为 10")
}
}
英文:
When recovering you will exit the current function. In this case you can easily wrap the task()
in a closure.
package main
import (
"log"
"sync"
"time"
)
func scheduleTask(task func() error, interval time.Duration, timeout time.Duration) {
//add waitgroup and mutex
var wg sync.WaitGroup
var mtx sync.Mutex
var startTime = time.Now()
//add each task to a goroutine and set interval and timeout to the function
wg.Add(1)
go func() {
defer wg.Done()
for {
//check if the time is up
if time.Since(startTime) > timeout {
break
}
mtx.Lock()
func() {
defer func() {
if r := recover(); r != nil {
log.Println("Recovering from panic:", r)
}
}()
task()
}()
mtx.Unlock()
}
}()
wg.Wait()
}
func main() {
var a = 0
scheduleTask(func() error {
time.Sleep(50 * time.Millisecond)
if a == 3 {
a++
panic("oops")
}
a++
return nil
}, time.Millisecond*100, time.Millisecond*1000)
log.Println(a)
if a != 10 {
log.Fatal("Expected it to be 10")
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论