でコンソール音楽プレーヤーに取り組んでいGoます。ユーザーがアルバムを選択して再生するたびに、ゴルーチンを起動してプレイリストをループします。
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()
}
}
ユーザーが新しいアルバムを選択したときに、このゴルーチンをキャンセルする方法が必要です。私はそうしています(しかし、それが最善の解決策であるとは確信していません)。context.Context
私はctx
ctx, cancel := context.WithCancel(context.Background())
したがって、UI イベント ハンドラーでplay() funcはcancel()、ゴルーチンになります。
これは、更新 UIforループ内をチェックすると機能します。
select {
case <-ctx.Done():
return err
default:
time.Sleep(50 * time.Millisecond)
}
その後、チャンネルctx.Done()が閉じられ、再生される次のアルバムがループの代わりに常に返されます。
キャンセルする方法はありcontext.Contextますか?
そうでない場合、このゴルーチン (および次のゴルーチン) をキャンセルするより良い方法はありますか?
別の方法として、待機グループを使用しようとしましたが、
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そのうちパニックになる