The example works also without cancellation tokens, just by throwing an OperationCanceledException. The result is the same - task1 is canceled while task2 is faulted. When using async/await a task is always in canceled state when throwing an OperationCanceledException. For me this is not a consistent behavior since you can not rely on the state. As long as you use the async/await pattern there is no problem (both canceled and faulted state throws an exception that can be caught).