kotlin - 异步构造生产者

标签 kotlin kotlin-coroutines

我有一种情况,我想异步使用ReceiveChannel构造一个produce,但是它挂了。这是一个简化的示例:

runBlocking {
    val deferredChannel = async {
        produce<String> { send("foo") }
    }

    val channel = deferredChannel.await()

    println("Got channel")

    val value = channel.receive()

    println("Got value $value")
}
println均未命中。可能存在某种协程僵局,但我不清楚在何处/如何进行。

如何异步生成ReceiveChannel

编辑:如果我将produce更改为produce(capacity = 1),则可以使用,但是为什么呢?不管生产者的能力如何,await()至少不成功吗?如果我想保持容量= 0,该怎么办?

最佳答案

It works if I change produce to produce(capacity = 1), but why is that? Shouldn't the await() succeed, at least, regardless of the producer's capacity?



检查您调用的produce()方法上的docs,尤其是检查我们具有的容量参数和Channel上的docs(重点是我的):

When capacity is 0 – it creates RendezvousChannel. This channel does not have any buffer at all. An element is transferred from sender to receiver only when send and receive invocations meet in time (rendezvous), so send suspends until another coroutine invokes receive and receive suspends until another coroutine invokes send.



这可能是它挂起的原因。您正在send线程上调用async,然后为其调用await ...但是,正如文档所说,尚无其他例程调用receive ...,因此它将挂起直到发生这种情况,在这种情况下将挂起。

检查Channel上的同一链接,我们还看到为什么给它一个大于0的数字可以解决这个问题(强调我的意思):

When capacity is positive, but less than UNLIMITED – it creates array-based channel with given capacity. This channel has an array buffer of a fixed capacity. Sender suspends only when buffer is full and receiver suspends only when buffer is empty.

关于kotlin - 异步构造生产者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56431199/

相关文章:

maven - Kapt 无法与 OpenJDK 16 一起正常工作

android-studio - 如何在 Android Studio 中为 Kotlin Multiplatform 配置 iOS 应用程序?

kotlin - 为什么在Kotlin异步方法中SecurityContextHolder.getContext()。authentication等于null?

android - 在 Android 上启动协程的正确方法是什么?

android - Kotlin 结构化并发 [协程] 模型是否适用于适合数据库写入的 UI?

android-studio - 将 GoogleSignInOptions.requestScopes() 用于 Gmail API 时如何定义范围?

android - 如何从 RecyclerView Adapter 调用 ViewModel.delete?

android - Dagger 2,在模块中提供应用上下文

kotlin - 从标签 Kotlin 的内部嵌套协程返回

android - 协程运行在主线程而不是后台