Асинхронное построение производителя - PullRequest
2 голосов
/ 03 июня 2019

У меня есть случай, когда я хочу построить 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?

1 Ответ

1 голос
/ 03 июня 2019

Это работает, если я меняю продукт на продукт (емкость = 1), но почему это так? Не должен ли await () завершиться успешно, по крайней мере, независимо от возможностей производителя?

Проверка документов для вызываемого вами метода produce() и, в частности, документов для параметра емкости и Channel у нас (выделение мое):

Когда емкость 0 - он создает RendezvousChannel. Этот канал вообще не имеет буфера . Элемент передается от отправителя к получателю только тогда, когда вызовы отправки и получения встречаются во время (рандеву), поэтому отправка приостанавливается до тех пор, пока другая сопрограмма не вызовет получение и получение приостановок, пока другая сопрограмма не вызовет отправку.

Это может быть причиной его зависания. Вы вызываете send в своем потоке async, а затем await для этого ... однако, как утверждают в документах, никакая другая подпрограмма еще не вызывала receive ... поэтому она будет приостановлена, пока это не произойдет и в этом случае зависает.

Проверяя ту же самую ссылку на канале, мы также видим, почему присвоение ей числа больше 0 решает это (выделено мной):

Когда емкость положительна , но меньше, чем UNLIMITED - он создает канал на основе массива с заданной емкостью. Этот канал имеет буфер массива фиксированной емкости. Отправитель приостанавливается только тогда, когда буфер заполнен, а получатель приостанавливается только тогда, когда буфер пуст .

...