【问题标题】:Coroutine canceled when the inner flow is collected收集内部流时取消协程
【发布时间】:2021-11-07 15:50:00
【问题描述】:

在这段代码中,好像是协程遇到一个收集到的流就取消了。

fun main() = runBlocking {
    println("Hi, world!")
    CoroutineScope(Dispatchers.Default).launch {
        innerSuspend()
        println("Bye, world!")
    }.join()
    println("task ended.")
}

suspend fun innerSuspend() {
    println("run: innerSuspend")
    innerFlow().collect {
        println("innerCallback : $it")
    }
}

suspend fun innerFlow() = callbackFlow {
    trySend("U r world?")
    awaitClose { close() }
}

我希望上面代码的结果看起来像这样:

嗨,世界!
运行:innerSuspend
innerCallback : 你的世界?
再见,世界!
任务结束。

但是,出乎意料,Bye, world!却没有显示出来。

嗨,世界!
运行:innerSuspend
innerCallback : 你的世界?

为什么会发生这种情况,我该如何解决?

【问题讨论】:

  • 另外,调用launch { .. }.join()没有意义,你也可以调用suspend函数。如果您确实想切换调度程序,只需使用 withContext(Dispatchers.Default) { ... } 包装您的暂停调用。

标签: kotlin kotlin-coroutines coroutine flow


【解决方案1】:

你的协程没有被取消。它仍然处于暂停状态,等待您的 Flow 中的下一个项目。您设计了一个永不关闭的 Flow,因此在其上调用 collect() 将永远挂起。

您将close() 调用放在awaitClose { } 中,就好像您只希望它在它已经关闭后才关闭,这没有任何意义。你应该输入close()

suspend fun innerFlow() = callbackFlow {
    trySend("U r world?")
    close()
}

【讨论】:

  • 我不知道Flow 会是个问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-07
  • 1970-01-01
  • 2021-01-04
  • 2021-12-24
  • 2020-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多