Pembersihan dengan finally dan NonCancellable
Lepaskan sumber daya dalam coroutine yang dibatalkan menggunakan finally dan withContext(NonCancellable).
Pembersihan dengan finally dan NonCancellable adalah pelajaran Kotlin Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Kotlin Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Kotlin Academy mencakup 4 pelajaran total.
Pembatalan dan finally
Saat korutin dibatalkan, titik penangguhan melempar CancellationException. Kode di dalam blok finally selalu dijalankan—namun finally itu sendiri berjalan dalam konteks korutin yang sudah dibatalkan.
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
try {
delay(1000)
} finally {
println("finally: cleaning up")
}
}
delay(50)
job.cancel()
job.join()
}Masalah: Penangguhan di dalam finally
Jika Anda mencoba melakukan delay atau penangguhan lain di dalam finally dari korutin yang dibatalkan, pengecualian akan langsung dilempar karena konteksnya sudah dibatalkan.
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)
Bungkus panggilan penangguhan di dalam finally dengan withContext(NonCancellable) agar panggilan tersebut berjalan dalam konteks yang tidak dapat dibatalkan meskipun induknya sudah dibatalkan.
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()
}Kapan Menggunakan NonCancellable
Gunakan NonCancellable untuk: menutup koneksi basis data, mengosongkan log, mengirim peristiwa analitik, atau melakukan pembersihan asinkron apa pun yang harus selesai terlepas dari pembatalan.
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 Bukan Cakupan
NonCancellable adalah Job yang dapat diteruskan ke withContext. Jangan menggunakannya secara langsung sebagai cakupan korutin—gunakan hanya dalam pembersihan 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() }
}Pembersihan Beberapa Sumber Daya
Rangkai beberapa operasi pembersihan di dalam satu blok 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() }
}Pola Coba/Tangkap/Akhir
Gabungkan pola coba-tangkap untuk kesalahan bisnis dengan blok akhir untuk pembersihan—ini adalah pola terstruktur standar.
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()
}Urutan Pembersihan
Blok akhir dijalankan dalam urutan kebalikan dari tingkat bersarangnya. Blok coba-akhir bagian luar dijalankan setelah blok bagian dalam, sama seperti dalam kode Java/Kotlin biasa.
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() }
}Penggunaan untuk Sumber Daya AutoCloseable
Untuk sumber daya AutoCloseable, gunakan ekstensi Kotlin use { } yang secara otomatis memanggil close(), bahkan saat terjadi pengecualian atau pembatalan.
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)
}Mencatat Alasan Pembatalan
Ambil pesan pembatalan dari CancellationException di dalam blok penanganan atau pembersihan akhir untuk mencatat alasan korutin berhenti.
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()
}Pembersihan CoroutineScope dengan Job.invokeOnCompletion
Job.invokeOnCompletion mendaftarkan panggilan balik yang dijalankan saat tugas selesai karena alasan apa pun—alternatif untuk finally dalam pembersihan di tingkat induk.
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()
}Pemeriksaan Singkat
Apa tujuan withContext(NonCancellable) di dalam blok finally?
Ringkasan
finally selalu dijalankan saat pembatalan. Bungkus panggilan penangguhan di dalam finally dengan withContext(NonCancellable) agar panggilan tersebut selesai meskipun terjadi pembatalan. Gunakan use { } untuk sumber daya AutoCloseable.
Belajar Kotlin dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 51
- Pelajaran
- 203
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Pembersihan dengan finally dan NonCancellable” gratis?
Ya — teks lengkap “Pembersihan dengan finally dan NonCancellable” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Kotlin Academy, upgrade ke CoddyKit PRO. Kursus Kotlin Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Pembersihan dengan finally dan NonCancellable”?
Lepaskan sumber daya dalam coroutine yang dibatalkan menggunakan finally dan withContext(NonCancellable). Kamu berlatih Kotlin Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Kotlin Academy?
Tidak diperlukan pengalaman sebelumnya. Kotlin Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Pembersihan dengan finally dan NonCancellable” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Kotlin Academy ini?
Ya. Setiap pelajaran Kotlin Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Pembatalan Kooperatif: isActive dan ensureActive
- withTimeout dan withTimeoutOrNull
- Pembersihan dengan finally dan NonCancellable
- Propagasi Pembatalan dalam Hierarki Coroutine