Sobes.tech
Middle+

Jak zaimplementowałbyś nieodwołalną korutynę?

sobes.tech AI

Odpowiedź od AI

Aby zaimplementować nieodwołalną korutynę, można użyć kontekstu NonCancellable.

import kotlinx.coroutines.*

suspend fun performNonCancellableOperation() {
    coroutineScope {
        launch {
            // Ta korutyna może zostać odwołana
            delay(1000)
            println("Ta korutyna została wykonana")
        }

        withContext(NonCancellable) {
            // Ta korutyna nie zostanie odwołana, nawet jeśli jej zakres nadrzędny zostanie odwołany
            try {
                delay(2000) // Symulacja długotrwałej operacji
                println("Operacja nieodwołalna zakończona")
            } catch (e: CancellationException) {
                // Korutyna nadal może otrzymać CancellationException
                // w niektórych przypadkach (np. zamknięcie aplikacji),
                // ale nie będzie odwoływana reaktywnie na odwołanie nadrzędne.
                println("Operacja nieodwołalna została odwołana: ${e.message}")
            } finally {
                // Ten blok zostanie wykonany nawet w przypadku odwołania
                println("Operacja nieodwołalna zakończona (finally)")
            }
        }
    }
}

Użycie NonCancellable jest przydatne do wykonywania operacji końcowych, takich jak zapisywanie danych czy zwalnianie zasobów, gdy korutyna została odwołana.

Ważne jest, aby pamiętać, że NonCancellable czyni korutynę niewrażliwą na odwołanie z kontekstu, ale nadal może ona zostać odwołana przy zamknięciu maszyny wirtualnej lub w innych ekstremalnych przypadkach. Dodatkowo, jeśli wewnątrz withContext(NonCancellable) wywołuje się funkcję zawieszającą, która sama sprawdza odwołanie (np. delay), może ona rzucić CancellationException. Dlatego zaleca się używanie try-catch-finally do obsługi takich sytuacji.