
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.