Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin coroutines `runBlocking`

I am learning Kotlin coroutines. I've read that runBlocking is the way to bridge synchronous and asynchronous code. But what is the performance gain if the runBlocking stops the UI thread? For example, I need to query a database in Android:

    val result: Int     get() = runBlocking { queryDatabase().await() }  private fun queryDatabase(): Deferred<Int> {     return async {         var cursor: Cursor? = null         var queryResult: Int = 0         val sqlQuery = "SELECT COUNT(ID) FROM TABLE..."         try {             cursor = getHelper().readableDatabase.query(sqlQuery)             cursor?.moveToFirst()             queryResult = cursor?.getInt(0) ?: 0         } catch (e: Exception) {             Log.e(TAG, e.localizedMessage)         } finally {             cursor?.close()         }         return@async queryResult     } } 

Querying the database would stop the main thread, so it seems that it would take the same amount of time as synchronous code? Please correct me if I am missing something.

like image 342
Angelina Avatar asked Sep 14 '18 11:09

Angelina


People also ask

What is runBlocking in coroutines?

runBlocking is almost never a tool you use in production. It undoes the asynchronous, non-blocking nature of coroutines. You can use it if you happen to already have some coroutine-based code that you want to use in a context where coroutines provide no value: in blocking calls.

What is the use of runBlocking in Kotlin?

Usually, runBlocking it is used in unit tests in Android or in some other cases of synchronous code. Keep in mind that runBlocking is not recommended for production code. runBlocking builder does almost the same thing as launch builder: it creates a coroutine and calls its start function.

Should I use runBlocking?

runBlocking() - use when you need to bridge regular and suspending code in synchronous way, by blocking the thread. Just don't overuse it. Don't treat runBlocking() as a quick fix for calling suspend functions. Always think if instead you shouldn't propagate suspending to the caller.

How do you wait for coroutine to finish Kotlin?

We can wait for the coroutine to finish by calling join() on the Job. For example, suppose we have a suspend function to download some files. We can launch this coroutine and capture the resulting job, which we can later use to join — to wait for the operation to complete.


1 Answers

runBlocking is the way to bridge synchronous and asynchronous code

I keep bumping into this phrase and it's very misleading.

runBlocking is almost never a tool you use in production. It undoes the asynchronous, non-blocking nature of coroutines. You can use it if you happen to already have some coroutine-based code that you want to use in a context where coroutines provide no value: in blocking calls. One typical use is JUnit testing, where the test method must just sit and wait for the coroutine to complete.

You can also use it while playing around with coroutines, inside your main method.

The misuse of runBlocking has become so widespread that the Kotlin team actually tried to add a fail-fast check which would immediately crash your code if you call it on the UI thread. By the time they did this, it was already breaking so much code that they had to remove it.

like image 64
Marko Topolnik Avatar answered Sep 20 '22 10:09

Marko Topolnik