我正在使用 Go
编写控制台音乐播放器。每当用户选择并播放一个专辑时,我会启动一个 Goroutine 来循环播放列表。
playlist := make([]*Media, 0)
for _, path := range album.Paths {
media, err := NewMediaFromPath(path)
// return err
playlist = append(playlist, media)
}
for idx := range playlist {
player.SetMedia(playlist[idx])
err = player.Play()
// check err
status, err := player.MediaState()
// check err
for status != MediaEnded && status != MediaStopped {
// update UI and check player status
// loop until the song finishes
status, err = player.MediaState()
}
}
我需要一种方法,可以在用户选择新专辑时取消此goroutine。我正在使用
context.Context
来实现这一点(但我不确定这是最好的解决方案)。我创建了
ctx
。 ctx, cancel := context.WithCancel(context.Background())
所以在UI事件处理程序中,play()
函数
将取消
goroutine。
一旦我在更新UI for
循环内部进行检查,就可以起作用:
select {
case <-ctx.Done():
return err
default:
time.Sleep(50 * time.Millisecond)
}
然后,通道ctx.Done()
被关闭,接下来播放的专辑将永远只返回一次而不是循环。
有没有一种方法可以重新取消context.Context
?
如果没有,是否有更好的方法来取消这个goroutine(和以下的goroutines)?
或者,我尝试使用waitgroups,
go func() {
wg.Wait()
wg.Add(1)
err = playAlbum(
done,
player,
*albums[s],
list,
status,
)
wg.Done()
// handle err
}()
但是我遇到了一个 sync: WaitGroup is reused before previous Wait has returned
的恐慌