Kotlin Academy · Les

Opruimen met finally en NonCancellable

Maak resources vrij in geannuleerde coroutines met finally en withContext(NonCancellable).

Les 3 van 413 stappen

Opruimen met finally en NonCancellable is een gratis Kotlin Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Kotlin Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Kotlin Academy bevat in totaal 4 lessen.

Annulering en finally

Wanneer een coroutine wordt geannuleerd, werpen suspensiepunten CancellationException op. Code in finally-blokken wordt altijd uitgevoerd — maar finally zelf draait in een geannuleerde coroutinecontext.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            delay(1000)
        } finally {
            println("finally: cleaning up")
        }
    }
    delay(50)
    job.cancel()
    job.join()
}

Probleem: opschorten in finally

Als je in finally van een geannuleerde coroutine delay of een andere opschorting probeert uit te voeren, wordt er direct een uitzondering opgeworpen omdat de context al geannuleerd is.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            delay(1000)
        } finally {
            // delay(100) // throws CancellationException here!
            println("Sync cleanup OK; async cleanup needs NonCancellable")
        }
    }
    delay(50); job.cancel(); job.join()
}

withContext(NonCancellable)

Wikkel aanroepen die kunnen opschorten in finally met withContext(NonCancellable), zodat ze ook na annulering van de ouder in een niet-annuleerbare context worden uitgevoerd.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            delay(1000)
        } finally {
            withContext(NonCancellable) {
                delay(100)  // OK: runs despite cancellation
                println("Async cleanup complete")
            }
        }
    }
    delay(50); job.cancel(); job.join()
}

Wanneer gebruik je NonCancellable?

Gebruik NonCancellable voor het sluiten van databaseverbindingen, het wegschrijven van logboeken, het verzenden van analysegebeurtenissen of andere asynchrone opruimacties die ongeacht annulering moeten worden voltooid.

import kotlinx.coroutines.*
suspend fun closeConnection() {
    println("Closing DB connection...")
    delay(50) // simulate async close
    println("Connection closed")
}
fun main() = runBlocking {
    val job = launch {
        try { delay(1000) }
        finally { withContext(NonCancellable) { closeConnection() } }
    }
    delay(50); job.cancel(); job.join()
}

NonCancellable is geen bereik

NonCancellable is een Job die je aan withContext kunt doorgeven. Gebruik het niet rechtstreeks als coroutinebereik — gebruik het alleen bij het opruimen in finally.

import kotlinx.coroutines.*
fun main() = runBlocking {
    // WRONG usage:
    // launch(NonCancellable) { ... } // launches a coroutine that cannot be cancelled
    // RIGHT usage:
    launch {
        try { delay(500) }
        finally {
            withContext(NonCancellable) {
                println("Safe cleanup")
            }
        }
    }.also { delay(50); it.cancel(); it.join() }
}

Meerdere resources opruimen

Combineer meerdere opruimacties in één blok met withContext(NonCancellable).

import kotlinx.coroutines.*
fun main() = runBlocking {
    launch {
        try {
            delay(1000)
        } finally {
            withContext(NonCancellable) {
                delay(20); println("Step 1: flush cache")
                delay(20); println("Step 2: close socket")
                delay(20); println("Step 3: log audit")
            }
        }
    }.also { delay(50); it.cancel(); it.join() }
}

Het try/catch/finally-patroon

Combineer try-catch voor fouten in de bedrijfslogica met finally voor het opruimen — dit is het standaardpatroon voor gestructureerde code.

import kotlinx.coroutines.*
fun main() = runBlocking {
    launch {
        try {
            delay(100)
            throw RuntimeException("business error")
        } catch (e: RuntimeException) {
            println("Handling: ${e.message}")
        } finally {
            withContext(NonCancellable) {
                println("Always cleanup")
            }
        }
    }.join()
}

Volgorde van opruimen

Finally-blokken worden uitgevoerd in omgekeerde volgorde van nesting. De buitenste try-finally wordt uitgevoerd na de binnenste blokken, net als in gewone Java/Kotlin-code.

import kotlinx.coroutines.*
fun main() = runBlocking {
    launch {
        try {
            try {
                delay(1000)
            } finally { println("Inner cleanup") }
        } finally { println("Outer cleanup") }
    }.also { delay(50); it.cancel(); it.join() }
}

use() voor AutoCloseable-resources

Gebruik voor AutoCloseable-resources Kotlin’s use { }-extensie. Deze roept automatisch close() aan, ook bij uitzonderingen of annulering.

import kotlinx.coroutines.*
class Connection : AutoCloseable {
    init { println("Opened") }
    override fun close() { println("Closed") }
    suspend fun query(): String { delay(50); return "result" }
}
fun main() = runBlocking {
    val result = Connection().use { it.query() }
    println(result)
}

De reden van annulering vastleggen

Haal het annuleringsbericht op uit CancellationException in catch of finally om vast te leggen waarom een coroutine is gestopt.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            delay(1000)
        } catch (e: CancellationException) {
            println("Cancelled: ${e.message}")
            throw e
        }
    }
    delay(50)
    job.cancel("user navigated away")
    job.join()
}

CoroutineScope opruimen met invokeOnCompletion

Job.invokeOnCompletion registreert een terugbelfunctie die wordt uitgevoerd wanneer de taak om welke reden dan ook is voltooid — een alternatief voor finally bij het opruimen op het niveau van het bovenliggende bereik.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        delay(1000)
    }
    job.invokeOnCompletion { cause ->
        if (cause != null) println("Ended with: ${cause::class.simpleName}")
        else println("Completed normally")
    }
    delay(50)
    job.cancel()
    job.join()
}

Korte controle

Wat is het doel van withContext(NonCancellable) in een finally-blok?

Samenvatting

finally wordt altijd uitgevoerd bij annulering. Wikkel aanroepen die kunnen opschorten in finally met withContext(NonCancellable), zodat ze ondanks annulering worden voltooid. Gebruik use { } voor AutoCloseable-resources.

Gratis beginnen

Leer Kotlin met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
51
Lessen
203

Veelgestelde vragen

Is de les “Opruimen met finally en NonCancellable” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Kotlin Academy, waaronder “Opruimen met finally en NonCancellable”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Kotlin Academy bevat in totaal 4 lessen.

Wat leer ik in “Opruimen met finally en NonCancellable”?

Maak resources vrij in geannuleerde coroutines met finally en withContext(NonCancellable). Je oefent met Kotlin Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Kotlin Academy te beginnen?

Ervaring vooraf is niet nodig. Kotlin Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Opruimen met finally en NonCancellable”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Kotlin Academy?

Ja. Elke les over Kotlin Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Coöperatieve annulering: isActive en ensureActive
  2. withTimeout en withTimeoutOrNull
  3. Opruimen met finally en NonCancellable
  4. Annuleringspropagatie in coroutinehiërarchieën
← Terug naar Kotlin Academy