receive
Retrieves an element, removing it from the channel.
This function suspends if the channel is empty, waiting until an element is available. If the channel is closed for receive
, an exception is thrown (see below).
val channel = Channel<Int>()
launch {
val element = channel.receive() // suspends until 5 is available
check(element == 5)
}
channel.send(5)
Suspending and cancellation
This suspending function is cancellable: if the Job of the current coroutine is cancelled while this suspending function is waiting, this function immediately resumes with CancellationException. There is a prompt cancellation guarantee: even if receive managed to retrieve the element from the channel, but was cancelled while suspended, CancellationException will be thrown, and, if the channel has an onUndeliveredElement
callback installed, the retrieved element will be passed to it. See the "Undelivered elements" section in the Channel documentation for details on handling undelivered elements. See suspendCancellableCoroutine for the low-level details of prompt cancellation.
Note that this function does not check for cancellation when it manages to immediately receive an element without suspending. Use ensureActive or CoroutineScope.isActive to periodically check for cancellation in tight loops if needed:
val channel = Channel<Int>()
launch { // a very fast producer
while (true) {
channel.send(42)
}
}
val consumer = launch { // a slow consumer
while (isActive) {
val element = channel.receive()
// some slow computation involving `element`
}
}
delay(100.milliseconds)
consumer.cancelAndJoin()
Receiving from a closed channel
Attempting to receive from a closed channel while there are still some elements will successfully retrieve an element from the channel.
When a channel is closed and there are no elements remaining, the channel becomes closed for
receive
. After that, receive will rethrow the same (in the===
sense) exception that was passed to SendChannel.close, or ClosedReceiveChannelException if none was given.
Related
This function can be used in select invocations with the onReceive clause. Use tryReceive to try receiving from this channel without waiting and throwing. Use receiveCatching to receive from this channel without throwing.