kotlin - 收集内部流时取消协程
问题描述
在这段代码中,当协程遇到一个收集的流时,它似乎被取消了。
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 :你的世界?
为什么会发生这种情况,我该如何解决?
解决方案
你的协程没有被取消。它仍然处于暂停状态,等待您的 Flow 中的下一个项目。你设计了一个永不关闭的 Flow,所以调用collect()
它会永远挂起。
你把close()
调用放在里面awaitClose { }
,好像你只希望它在它已经关闭后才关闭,这没有意义。你应该把close()
.
suspend fun innerFlow() = callbackFlow {
trySend("U r world?")
close()
}
推荐阅读
- python-3.x - Python多处理:如何限制等待进程的数量?(使用 Python 3.7 或更高版本。)
- python - python patsy:加权效应编码又名加权和(偏差)编码
- android - 在 GCP api 网关中发送签名证书的 SHA 1 指纹作为 api 密钥验证的一部分是否安全?
- bootstrap-4 - Plotly Dash:由于滚动,下拉菜单在 DataTable 中不可见
- image - WhatsApp跟踪和匹配图像
- yaml - 如何将 .env 文件连接到 config.yml?
- ios - IOS,如何删除ViewControllers之间的半暗过渡动画
- terraform - 如何在 Terraform 中创建尚不存在的 IAM 角色?
- angular - 错误:
属性变换:预期数字,“translate(NaN, 0) scale(1)”。顶点图 - java - 用正则表达式替换第一行文本中所有出现的特定字符