You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Channel轮询异常:发送的Item未全部被receive接收

Kotlin Channel轮询丢失Item问题排查

你的问题核心出在Channel的迭代逻辑和手动receive()重复调用上,导致一半的Item被无声丢弃,具体分析如下:

问题原因

for (element in basketChannel) 这个循环本身就是Kotlin Channel提供的迭代式接收语法——每次循环迭代时,底层会自动调用receive()从Channel取出一个元素并赋值给element。而你在循环体内又额外调用了一次basketChannel.receive(),这就意味着:

  • 第一次循环:取出Item1(通过迭代)打印,然后又取出Item2(手动receive)但没处理,直接丢弃
  • 第二次循环:取出Item3(迭代)打印,然后取出Item4(手动receive)丢弃
    最终只打印了Item1和Item3,Item2、Item4被无意义的receive()消耗却没输出。

修复方案

只需要保留一种接收方式即可,两种可选:

方案1:保留for-in迭代(推荐,更简洁)

删掉循环内多余的receive():

fun startPolling() {
    viewModelScope.launch {
        Log.e(TAG, "Starting Polling")
        for (element in basketChannel) {
            logE("basketChannel Item poll -> $element")
            // 移除多余的basketChannel.receive()
        }
    }
}

方案2:手动循环调用receive()

如果想显式用poll/receive的方式,改用while循环:

fun startPolling() {
    viewModelScope.launch {
        Log.e(TAG, "Starting Polling")
        while (true) {
            val element = basketChannel.receive()
            logE("basketChannel Item poll -> $element")
        }
    }
}

额外说明

  • Channel的for-in迭代会自动处理Channel的关闭逻辑:当Channel被关闭且缓冲区为空时,循环会自动终止
  • 手动receive()在Channel关闭后会抛出ClosedReceiveChannelException,如果需要处理关闭,可以用receiveCatching()替代

内容的提问来源于stack exchange,提问作者Compose Learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:45:11