Sobes.tech
Middle+

How would you implement an uninterruptible coroutine?

sobes.tech AI

Answer from AI

To implement a non-cancellable coroutine, you can use the NonCancellable context.

import kotlinx.coroutines.*

suspend fun performNonCancellableOperation() {
    coroutineScope {
        launch {
            // This coroutine can be cancelled
            delay(1000)
            println("This coroutine has completed")
        }

        withContext(NonCancellable) {
            // This coroutine will not be cancelled, even if its parent scope is cancelled
            try {
                delay(2000) // Simulate a long operation
                println("Non-cancellable operation completed")
            } catch (e: CancellationException) {
                // The coroutine can still receive a CancellationException
                // in certain cases (e.g., when closing the application),
                // but it will not be reactively cancelled on parent cancellation.
                println("Non-cancellable operation was cancelled: ${e.message}")
            } finally {
                // This block will execute even if cancelled
                println("Non-cancellable operation finished (finally)")
            }
        }
    }
}

Using NonCancellable is useful for performing finalizing operations, such as saving data or releasing resources, when a coroutine has been cancelled.

It is important to remember that NonCancellable makes the coroutine insensitive to cancellation from the context, but it can still be cancelled when the virtual machine is shutting down or in other extreme cases. Also, if a suspending function called inside withContext(NonCancellable) checks for cancellation itself (e.g., delay), it may throw a CancellationException. Therefore, it is recommended to use try-catch-finally to handle such situations.

How would you implement an uninterruptible coroutine… - sobes.tech