繁体   English   中英

Kotlin协同程序`runBlocking`

[英]Kotlin coroutines `runBlocking`

我正在学习Kotlin协同程序。 我已经读过runBlocking是桥接同步和异步代码的方法。 但是如果runBlocking停止UI线程,性能提升是多少? 例如,我需要在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
    }
}

查询数据库会停止主线程,所以它似乎需要与同步代码相同的时间? 如果我错过了什么,请纠正我。

runBlocking是桥接同步和异步代码的方法

我一直在碰到这句话,这是非常误导的。

runBlocking 几乎从不是您在生产中使用的工具。 它解除了协同程序的异步,非阻塞性​​质。 如果你碰巧已经有一些基于协同程序的代码,你想在协同程序没有提供任何价值的上下文中使用它,你可以使用它:阻塞调用。 一个典型的用途是JUnit测试,其中测试方法必须坐下并等待协程完成。

您也可以在main方法中使用协同程序时使用它。

滥用runBlocking已经变得如此普遍,以至于Kotlin团队实际上试图添加一个快速失败检查,如果你在UI线程上调用它会立即崩溃你的代码。 当他们这样做时,已经打破了这么多代码,他们不得不删除它。

实际上你使用runBlocking来调用“阻塞”代码中的暂停函数,否则这些代码将无法在那里调用或者换句话说:你用它来调用协同程序上下文之外的suspend函数(在你的例子中,传递给async的块是suspend功能)。 此外(更明显的是,正如名称本身所暗示的那样),然后呼叫是阻塞呼叫。 因此,在您的示例中,它被执行就好像没有像async这样的东西。 它等待(阻塞可阻塞 )直到runBlocking所有内容都完成。

例如,假设库中的函数如下:

suspend fun demo() : Any = TODO()

该方法不能从例如main调用。 对于这种情况,您可以使用runBlocking ,例如:

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编程指南感兴趣。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM