У меня есть простой производитель и потребитель, которые используют каналы Coroutine.Вот упрощенная версия:
class Producer {
suspend fun start(): ReceiveChannel<String> {
val channel = Channel<String>(Channel.UNLIMITED)
// Asynchronous channel.send(it) from an object callback
channel.invokeOnClose {
// Channel is closed...
}
return channel
}
}
class Consumer : CoroutineScope {
private val producer = Producer()
private val job = Job()
override val coroutineContext = job + Dispatchers.Default
fun start() {
launch {
val channel = producer.start()
for (currentValue in channel) {
// use currentValue
}
}
}
fun stop() {
job.cancel()
}
}
Producer
создает канал, а затем заполняет его значениями из асинхронного задания.Consumer
перебирает его и использует значения.
Я ожидал, что когда я вызову job.cancel()
от потребителя, итератор канала выдаст, а канал закроется.Обратный вызов invokeOnClose
никогда не вызывается.
Я мог бы сохранить ссылку на канал в Consumer
и сделать channel.close()
.Я хочу знать, есть ли более разумное решение для этого.Может быть, другой способ перебора значений канала?Спасибо?
Редактировать
Похоже, что использование
launch {
val channel = producer.start()
channel.consumeEach { currentValue ->
// use currentValue
}
}
Сработает.Однако consumeEach()
помечен как устаревший.