Kotlin协程`runBlocking` [英] Kotlin coroutines `runBlocking`

查看:597
本文介绍了Kotlin协程`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.

推荐答案

实际上,您使用suspend协程上下文之外的函数(在您的示例中,传递给async的块是suspend函数).同样(更明显的是,顾名思义,顾名思义),该调用也是阻塞调用.因此,在您的示例中,它的执行就像没有适当的async一样.它等待(可中断地阻塞 ),直到runBlocking -block中的所有内容都结束.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆