liveBook · Manning

Task cancellation

As explained in Kotlin in Action, 2E

Task cancellation is a request or mechanism for stopping an asynchronous or in-progress operation before it completes normally.

Task cancellation stops coroutine work before normal completion. It prevents wasted network, CPU, and battery use when a result is no longer needed, and helps avoid coroutines retaining resources or memory unnecessarily. In concurrent computations, cancellation also lets remaining work stop when a failed task makes a shared result impossible. section 15.2 section 18.2.1

fun main() {
    runBlocking(Dispatchers.Default) {
        val launchedJob = launch {      #1
            log("I'm launched!")
            delay(1000.milliseconds)
            log("I'm done!")
        }
        val asyncDeferred = async {     #2
            log("I'm async")
            delay(1000.milliseconds)
            log("I'm done!")
        }
        delay(200.milliseconds)
        launchedJob.cancel()            #3
        asyncDeferred.cancel()          #3
    }
}
 
// 0 [main @coroutine#2] I'm launched!
// 7 [main @coroutine#3] I'm async

Keep the Job returned by launch or the Deferred returned by async as a cancellation handle. Calling cancel() requests that each coroutine stop before its delayed work completes. section 15.2.1

Cancellation follows the structured coroutine hierarchy: cancelling a parent cancels every child, including deeply nested descendants. A scope’s Job can be cancelled in the same way, allowing one lifecycle boundary to clean up related work rather than leaving rogue coroutines behind. section 15.2.3 section 15.0

Treat cancellation as a normal control path rather than an exceptional afterthought:

  • Expect CancellationException at suspension points. Do not swallow it with broad catches; rethrow it or catch only the specific recoverable exception. section 15.2.4
  • Make CPU-heavy suspending code cooperative. The suspend modifier alone does not create a cancellation point; use cancellable calls or utilities such as ensureActive, yield, and isActive. section 15.2.5
  • Release resources on every exit path. Put cleanup in finally, or use use with AutoCloseable resources, because cancellation can interrupt work before an explicit close call. section 15.2.8
  • Choose a scope whose lifetime matches the work. Framework scopes may cancel on screen navigation or client disconnect; move independent work to a longer-lived application scope. section 15.2.9

Cancellation at a suspension point

A coroutine cancelled while waiting in delay throws CancellationException before later statements run. Statements after that suspension point are skipped, but adjacent statements with no cancellation point between them execute together. This explains why CPU-only loops need explicit cooperation. section 15.2.4 section 15.2.5

Uncaught failure normally travels from a child to its parent. The parent cancels sibling coroutines, completes with the same exception, and propagates it upward. A SupervisorJob changes this failure relationship, while cancellation still depends on the scope hierarchy. section 18.2.1 section 18.3.1

How Kotlin in Action, 2E covers it

How deep it goes
Explains triggering, hierarchy propagation, suspension-point exceptions, cooperative CPU work, resource cleanup, and framework-managed scopes.
Examples
Uses launch and async handles, nested child coroutines, CPU-heavy loops, database connections, ViewModel scopes, Ktor requests, and failing sibling tasks.
What it assumes
Assumes familiarity with coroutines and suspending functions while explaining cancellation behavior at suspension points.
What you can do after
Build cancellable coroutine code, propagate cancellation correctly, and clean up resources across lifecycle and failure paths.
How it connects
Connects structured concurrency with Job, Deferred, coroutine scopes, suspension points, CancellationException, SupervisorJob, Android ViewModel, and Ktor.

Also explained in

Compare how 5 books explain task cancellation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.