I notice a strange behavior when trying to prematurely cancel from a Flow. Take a look at the following example.
This is a simple flow that emits integer values
I want to add that in 1.3.7 version emissions from flow builder now check cancellation status and are properly cancellable. So the code in question will work as expected
I came across a workaround in this related issue
I have replaced every single collect
with a safeCollect
function in my project:
/**
* Only proceed with the given action if the coroutine has not been cancelled.
* Necessary because Flow.collect receives items even after coroutine was cancelled
* https://github.com/Kotlin/kotlinx.coroutines/issues/1265
*/
suspend inline fun <T> Flow<T>.safeCollect(crossinline action: suspend (T) -> Unit) {
collect {
coroutineContext.ensureActive()
action(it)
}
}
I came up with this recently
it seems that it will only actually cancel if it reaches a suspending point and in your code that emits there is no such point
to solve this either add yield() between emissions or some other suspending function like delay(100)