【问题标题】:Why do kotlin coroutines block this code?为什么 kotlin 协程会阻塞这段代码?
【发布时间】:2020-08-11 16:00:23
【问题描述】:

为什么这段代码永远不会打印 Hello World?

runBlocking(Dispatchers.Main) {
    launch {
        delay(1)
        println("Hello world")
    }
}

但这会打印出来

runBlocking {
    launch {
        delay(1)
        println("Hello world")
    }
}

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    从我看到的第一个示例完全冻结应用程序(在按钮点击侦听器中使用时)。

    问题是你造成了死锁:

    1. Dispatchers.Main 通过将协程发布(调度)到主应用程序循环器来工作
    2. runBlocking 阻塞主应用线程
    3. 主循环器将永远无法运行已发布的协程,因为它正在等待 runBlocking 完成

    您可以通过使用Dispatchers.Main.immediate 稍微缓解“问题”,而不是使用更智能的基本调度程序版本 - 如果协程已经在主线程上运行并就地执行,它不会将协程发布到主循环器.

    这将允许您运行launch 块,但是delay 将再次发布协程以继续主循环并导致另一个死锁。

    第二个代码示例没有问题,因为在那里运行的协程不与主线程交互(runBlocking 除外)。

    【讨论】:

    • 注意runBlocking 通常应该使用never(在非测试代码中)可能很重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多