Home » Kotlin coroutine with timeout

Kotlin coroutine with timeout

Kotlin coroutine with timeout

1. Overview

In this article, we will learn to implement Coroutine with timeout in Kotlin.

2. Kotlin coroutine

A coroutine is a concurrency design pattern you can use to simplify code that executes asynchronously.

It takes a block of code to run, that works concurrently with the rest of the code. However, it is not bound to any thread. It may suspend its execution in one thread and resume in another one.

Kotlin coroutines are extremely inexpensive when compared with threads. Each time when we want to start a new task asynchronously, we can create a new coroutine. To start a new coroutine, we use one of the main “coroutine builders”: launch, async, or runBlocking.

3. Kotlin Coroutine with timeout

Often, we want to cancel the execution of a coroutine once its execution time has exceeded some timeout.

You can do this in any of the below ways. However, we recommend using the withTimeout function.

3.1. Cancel the Job reference after a delay

You can manually track the reference to the corresponding Job or Deferred and launch a separate coroutine to cancel the tracked one after delay.

Look at the following example. Assume we need to cancel the coroutine1 after 500 ms. After getting the reference of the coroutine1, (async returns the reference of the coroutine as instance of Deferred), we are cancelling it inside another coroutine2 after 500 ms.

fun main() = runBlocking {
    println("Getting values...")
    val coroutine1 : Deferred<String> = async {
        println("Coroutine 1")
        delay(1000) // assume coroutine takes about 1000 ms to complete
        "Executed"
    }
    val coroutine2 = launch {
        delay(500)
        coroutine1.cancel()
    }
    println(coroutine1.await())
}

3.2. Using withTimeout function

The withTimeout function takes the provided suspending block of code inside a coroutine with a specified timeout and throws a TimeoutCancellationException if the timeout was exceeded.

The timeout event is asynchronous with respect to the code running in the block and may happen at any time, even right before the return from inside of the timeout block. Note that you must close or release the resources that you open or acquire some resource inside the block.

fun main() = runBlocking {
    withTimeout(1300L) {
        repeat(1000) { i ->
            println("I'm sleeping $i ...")
            delay(500L)
        }
    }
}
/* prints
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
Exception in thread "main" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1300 ms
 at (Coroutine boundary. (:-1) 
 at FileKt$main$1$1.invokeSuspend (File.kt:-1) 
 at FileKt$main$1.invokeSuspend (File.kt:-1) 
*/

4. Conclusion

To sum up, we have learned to implement Coroutine with timeout in Kotlin. You can find code samples in our GitHub repository.

Leave a Reply

Your email address will not be published.