【问题标题】:Suspend function blocks main thread挂起功能块主线程
【发布时间】:2019-07-27 09:21:49
【问题描述】:

我很难理解协程。这是一个非常简单的设置。 longComputationdelay 都是挂起函数。第一个阻塞主线程,后者不阻塞。为什么?

CoroutineScope(Dispatchers.Main).launch {
    val result = longComputation() // Blocks
    delay(10_000) // Doesn't block
}

【问题讨论】:

  • 您是否尝试过在不同的线程上下文(例如withContext(IO))上运行任务?
  • 是的,这行得通。我想我必须回到基础。 delay 是否也在内部切换调度程序?不能说我看懂了delay的源码
  • No delay不需要另一个dispatcher,因为它是一个真正的挂起函数,不会在任何时候阻塞线程

标签: kotlin kotlin-android-extensions kotlin-coroutines


【解决方案1】:

这取决于。 longComputation 到底是做什么的? 当您将函数标记为suspend 时,这并不意味着您不能在其中包含阻塞代码。例如,看看这个:

suspend fun blockingSuspendFunction(){
    BigInteger(1500, Random()).nextProbablePrime()
}

suspend 函数内部的代码显然是占用 CPU 并阻塞调用者的东西。 按照惯例,不应该这样做,因为如果您调用挂起函数,您期望不会阻塞线程:

约定:挂起函数不会阻塞调用者线程。 (https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761)

要使这样的函数“表现为挂起函数”,必须将阻塞分派到另一个工作线程上,这(建议)应该发生在withContext

suspend fun blockingSuspendFunction() = withContext(Dispatchers.Default) {
    BigInteger.probablePrime(2048, Random())
}

【讨论】:

  • 正是你提到的。这是一个繁重的阻塞计算。突然间,“延续”的概念对我来说是有意义的。
猜你喜欢
  • 2020-03-13
  • 1970-01-01
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 2016-10-06
相关资源
最近更新 更多