awaitClose
Suspends the current coroutine until the channel is either closed or cancelled.
The given block will be executed unconditionally before this function returns. awaitClose { cleanup() }
is a convenient shorthand for the often useful form try { awaitClose() } finally { cleanup() }
.
This function can only be invoked directly inside the same coroutine that is its receiver. Specifying the receiver of awaitClose explicitly is most probably a mistake.
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 this function is ready to return, but was cancelled while suspended, CancellationException will be thrown. See suspendCancellableCoroutine for low-level details.
Example of usage:
val callbackEventsStream = produce {
val disposable = registerChannelInCallback(channel)
awaitClose { disposable.dispose() }
}
Internally, awaitClose is implemented using SendChannel.invokeOnClose. Currently, every channel can have at most one SendChannel.invokeOnClose handler. This means that calling awaitClose several times in a row or combining it with other SendChannel.invokeOnClose invocations is prohibited. An IllegalStateException will be thrown if this rule is broken.
Pitfall: when used in produce, if the channel is cancelled, awaitClose can either return normally or throw a CancellationException due to a race condition. The reason is that, for produce, cancelling the channel and cancelling the coroutine of the ProducerScope is done simultaneously.
Throws
if this channel already has a SendChannel.invokeOnClose handler registered.