Home > Article > Backend Development > Go - forever stop loop with context
I have an asynchronous process that is supposed to last forever, like this:
func asyncforevertask() { for { anytask() } } func main() { go asyncforevertask() server.run(8080) }
I want to be able to stop this for loop when a request reaches the server.
I know I need to use context.withcancel()
, but I don't know how to integrate it to make it work. I know the following syntax:
for { select { case <-ctx.Done: return case <-otherCh: // do smh. } }
But asyncforevertask
is not run by a signal from any otherch, but it runs forever. I'm a newbie and any kind of help is greatly appreciated.
You can use channels to do this:
var stopasync = make(chan struct{}) func asyncforevertask() { for { select { case <-stopasync: return default: } anytask() } }
To cancel, simply close the channel. You have to make sure the channel is closed only once, otherwise you will panic.
You can also do this via context:
func main() { ctx,cancel:=context.withcancel(context.background()) go asyncforevertask(ctx) ... } func asyncforevertask(ctx context.context) { for { select { case <-ctx.done(): return default: } anytask() } }
or:
func asyncforevertask(ctx context.context) { for { if ctx.err()!=nil { return } anytask() }
To stop, call the returned cancel
function:
... cancel()
If you also need to stop anytask
, you must always check for channel close or context close and return from the task.
The above is the detailed content of Go - forever stop loop with context. For more information, please follow other related articles on the PHP Chinese website!