Cancelling Coroutines in Kotlin by@timofeykrestyanov

Cancelling Coroutines in Kotlin

Read on Terminal Reader
Open TLDR
react to story with heart
react to story with light
react to story with boat
react to story with money
Coroutines provide a simple undo mechanism to solve problems with long-running operations or memory leaks. The cancellation of a coroutine is fully thread-safe and non-blocking. We can use cancellation in coroutines for easy resource cleaning or possibly some form of error logging. If the job is canceled, a ‘CancellationException` will be thrown. We can also combine these two calls into the ‘job.cancelAndJoin()` function. If we need to wait for the Job to be complete, we can use the `job.join().
image
Timofey Krestyanov HackerNoon profile picture

Timofey Krestyanov

I'm 5+ years of experience in building Mobile apps developer, I have worked on Android, and iOS projects

Overview

Sometimes we need to close some thread, and we can't just kill the thread as we need to free resources and close connections.


Coroutines provide a simple undo mechanism to solve such problems and problems with long-running operations or memory leaks.

Cancelling Jobs

Let's create an object using the Job() factory function:


suspend fun main() = coroutineScope {
    val job = Job()
}


This Job object represents a running coroutine. Coroutines whose results we don't need can cancel anytime we want by calling the job.cancel() function:


suspend fun main() = coroutineScope {
    val job = Job()
    launch(job) {
        repeat(1000) { i ->
           delay(50)
           println("$i")
      }
   }
   job.cancel()
}


The coroutine will be canceled without waiting for its actual completion. Calling cancel again does nothing.

The cancellation of a coroutine is fully thread-safe and non-blocking.

If we need to wait for the Job to be complete, we can use the job.join():


suspend fun main() = coroutineScope {
    val job = Job()
    launch(job) {
        repeat(1000) { i ->
           delay(50)
           println("$i")
      }
   }
   delay(500)
   job.cancel()
   job.join()
   println("Cancelled")
}


We can also combine these two calls into the job.cancelAndJoin() function.

Exception handling

If the job is canceled, a CancellationException will be thrown. We can catch it with try-catch-finally:


suspend fun main() = coroutineScope {
    val job = Job()
    launch(job) {
       try {
            repeat(1000) { i ->
                delay(50)
                println("$i")
            }
        } catch (e: CancellationException) {
            println(e)
        } finally {
            println("Finally")
        }
    }
    delay(500)
    job.cancelAndJoin()
    println("Cancelled")
}


СancelationException is a special exception to handle coroutine execution cancellation.

We can define behavior for all unhandled exceptions that occur in the current coroutine execution context. To do this, you can use CoroutineExceptionHandler, which is an interceptor for any exception.


CoroutineExceptionHandler { coroutineContext, throwable ->
    println(throwable)
}


We can catch an exception this way from any thread and define default behavior for all of them. CoroutineExceptionHandler is called last after an error has occurred.

Conclusion

Cancellation in coroutines is easy to use and is important for the performance of your application. We can use cancellation in coroutines for easy resource cleaning or possibly some form of error logging.

react to story with heart
react to story with light
react to story with boat
react to story with money
L O A D I N G
. . . comments & more!