Kotlin协程`runBlocking` [英] Kotlin coroutines `runBlocking`
问题描述
我正在学习Kotlin协程.我已经读到runBlocking
是桥接同步和异步代码的方式.但是,如果runBlocking
停止UI线程,性能会提高多少?
例如,我需要在Android中查询数据库:
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.
推荐答案
Actually you use runBlocking
to call suspending functions in "blocking" code that otherwise wouldn't be callable there or in other words: you use it to call suspend
functions outside of the coroutine context (in your example the block passed to async
is the suspend
function). Also (more obvious, as the name itself implies already), the call then is a blocking call. So in your example it is executed as if there wasn't something like async
in place. It waits (blocks interruptibly) until everything within the runBlocking
-block is finished.
例如,假设您的库中的函数如下:
For example assume a function in your library as follows:
suspend fun demo() : Any = TODO()
例如,该方法将无法调用. main
.在这种情况下,请使用runBlocking
,例如:
This method would not be callable from, e.g. main
. For such a case you use runBlocking
then, e.g.:
fun main(args: Array<String>) {
// demo() // this alone wouldn't compile... Error:() Kotlin: Suspend function 'demo' should be called only from a coroutine or another suspend function
// whereas the following works as intended:
runBlocking {
demo()
} // it also waits until demo()-call is finished which wouldn't happen if you use launch
}
关于性能提升:实际上,您的应用程序可能宁愿响应速度更快,而不是性能更高(有时性能也更高,例如,如果您有多个并行操作而不是多个顺序操作).但是,在您的示例中,分配变量时您已经阻塞了,因此我想说您的应用程序还没有变得更加响应.您可能希望异步调用查询,然后在响应可用后立即更新UI.因此,您基本上只是省略了runBlocking
,而是使用了类似launch
的名称.您可能也对使用以下工具进行UI编程的指南感兴趣协程.
Regarding performance gain: actually your application may rather be more responsive instead of being more performant (sometimes also more performant, e.g. if you have multiple parallel actions instead of several sequential ones). In your example however you already block when you assign the variable, so I would say that your app doesn't get more responsive yet. You may rather want to call your query asynchronously and then update the UI as soon as the response is available. So you basically just omit runBlocking
and rather use something like launch
. You may also be interested in Guide to UI programming with coroutines.
这篇关于Kotlin协程`runBlocking`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!