Coroutines – Dispatcher & Yield
Posted On May 3, 2020
Today another day in quarantine since the COVID-19 outbreak. So I thought let’s really learn how coroutines work instead of just using it and hope for the best. I did the codelab from Google that did a pretty good job for me to understand how it works.
I wanted to highlight how to dispatch a coroutine and how it could be shorter then you think.
To switch between any dispatcher, coroutines uses
withContext switches to the other dispatcher just for the lambda then comes back to the dispatcher that called it with the result of that lambda.
By default, Kotlin coroutines provides three Dispatchers:
Default. The IO dispatcher is optimized for IO work like reading from the network or disk, while the Default dispatcher is optimized for CPU intensive tasks.
This code doesn’t support coroutine cancellation, but it can! Coroutine cancellation is cooperative. That means your code needs to check for cancellation explicitly, which happens for you whenever you call the functions in kotlinx-coroutines.
withContext block only calls blocking calls it will not be cancelled until it returns from
To fix this, you can call
yield regularly to give other coroutines a chance run and check for cancellation. Here you would add a call to
yield between the network request and the database query. Then, if the coroutine is cancelled during the network request, it won’t save the result to the database.
You can also check cancellation explicitly, which you should do when making low-level coroutine interfaces.
Both Room and Retrofit use a custom dispatcher and do not use
Dispatchers.IO. Room will run coroutines using the default query and transaction
Executor that’s configured. Retrofit will create a new
Call object under the hood, and call enqueue on it to send the request asynchronously.
You do not need to use
withContext to call main-safe suspending functions. Since both Room and Retrofit provide main-safe suspending functions, it’s safe to orchestrate this async work from
By convention, you should ensure that
suspend functions written in your application are main-safe. That way it is safe to call them from any dispatcher, even