Why is the task is not cancelled when I call CancellationTokenSource's Cancel method in async method?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In .NET, cancellation is cooperative, not forced. Calling Cancel on a CancellationTokenSource only signals intent to cancel; the running operation must observe that token and stop itself. If your task continues running after Cancel, the code path is usually not checking the token or is awaiting APIs that ignore it.
Cancellation Is a Signal, Not a Kill Switch
A token has two roles:
- Producer side calls
Cancel. - Consumer side checks token and exits quickly.
If consumer code never checks token state, no cancellation happens.
This works because both loop and delay honor the token.
Why Cancel Seems Ignored
Common causes:
- Token was never passed into the async method.
- Method accepted token but never checked it.
- Underlying API call had no token overload.
- Work is CPU-bound loop with no cancellation checkpoint.
- Task already completed before cancel request.
A token can only affect code that cooperates.
CPU-Bound Work Must Check Explicitly
For CPU-heavy loops, insert periodic cancellation checks.
Without checkpoints, cancellation appears delayed or ineffective.
I O Calls Need Token-Aware APIs
If an awaited operation has a token overload, use it.
If the API lacks token support, cancellation may only occur between operations, not during the blocking call.
Correct Task State Expectations
After cooperative cancellation:
- Awaiting usually throws
OperationCanceledException. - Task status becomes canceled, not faulted.
If you catch and swallow OperationCanceledException, caller may think operation completed normally. Preserve cancellation semantics unless business logic requires conversion.
Linked Tokens and Timeout Policies
Real services often combine user cancellation and timeout cancellation.
This gives one cancellation path while keeping source intent separable.
Debugging Checklist
When task is not canceled as expected:
- Confirm the token instance passed to worker is the same one canceled.
- Confirm awaited APIs receive the token.
- Confirm loops call
ThrowIfCancellationRequestedor similar checks. - Confirm cancellation is not swallowed by broad catch blocks.
- Confirm operation was not already complete before cancel signal.
These checks usually isolate the issue quickly.
Common Pitfalls
- Treating
Cancelas thread abort behavior. - Creating a token but forgetting to pass it through call chains.
- Calling token-aware methods without token overloads.
- Swallowing cancellation exceptions and returning success.
- Missing checkpoints in long CPU-bound loops.
Summary
- .NET task cancellation is cooperative and requires explicit observation.
Cancelonly signals intent; worker code must honor it.- Pass tokens end-to-end and use token-aware API overloads.
- Add cancellation checkpoints in CPU-intensive logic.
- Preserve cancellation semantics so callers can respond correctly.

