0
0
GoHow-ToBeginner · 3 min read

How to Use context.WithCancel in Go: Simple Guide

In Go, context.WithCancel creates a new context that can be canceled manually by calling the returned cancel function. This allows you to stop work in goroutines early and clean up resources when needed.
📐

Syntax

The context.WithCancel function returns two values: a new Context and a cancel function. You call the cancel function to signal cancellation to all goroutines using that context.

  • ctx: The parent context, often context.Background() or context.TODO().
  • cancel: A function to call when you want to cancel the context.
go
ctx, cancel := context.WithCancel(parentCtx)
// Use ctx in goroutines
// Call cancel() to stop work
💻

Example

This example shows how to start a goroutine that listens for cancellation using context.WithCancel. When cancel() is called, the goroutine stops its work and exits cleanly.

go
package main

import (
	"context"
	"fmt"
	"time"
)

func worker(ctx context.Context) {
	for {
		select {
		case <-ctx.Done():
			fmt.Println("Worker: received cancellation signal, stopping.")
			return
		default:
			fmt.Println("Worker: working...")
			time.Sleep(500 * time.Millisecond)
		}
	}
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	go worker(ctx)

	// Let the worker run for 2 seconds
	time.Sleep(2 * time.Second)

	// Cancel the context to stop the worker
	cancel()

	// Wait a moment to see worker stop
	time.Sleep(1 * time.Second)
}
Output
Worker: working... Worker: working... Worker: working... Worker: working... Worker: received cancellation signal, stopping.
⚠️

Common Pitfalls

One common mistake is forgetting to call the cancel function, which can cause resource leaks because the context and its children remain active. Another is ignoring the ctx.Done() channel in goroutines, so they never stop when canceled.

Always call cancel() when the work is done or no longer needed, and check ctx.Done() in goroutines to handle cancellation properly.

go
/* Wrong: Not calling cancel() leads to resource leaks */
ctx, _ := context.WithCancel(context.Background())
// ... do work but never call cancel()

/* Right: Call cancel() to release resources */
ctx, cancel := context.WithCancel(context.Background())
// ... do work
cancel()
📊

Quick Reference

  • context.WithCancel(parentCtx): creates a cancelable context.
  • cancel(): call to stop work and release resources.
  • ctx.Done(): channel to listen for cancellation signal.
  • Use in goroutines to stop work early.
  • Always call cancel() to avoid leaks.

Key Takeaways

Use context.WithCancel to create a context you can cancel manually.
Always call the cancel function to avoid resource leaks.
Check ctx.Done() in goroutines to stop work when canceled.
context.WithCancel helps manage goroutine lifecycles cleanly.
Use context.Background() as the parent context if none exists.