https://kotlinlang.org logo
Title
a

ansman

04/15/2019, 10:17 PM
Hmm, this code hangs forever for me using 1.3.30:
withTimeoutOrNull(100) {
    suspendCoroutine<Unit> { cont ->
        (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
            .hideSoftInputFromWindow(windowToken, 0, object : ResultReceiver(handler) {
                override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
                    cont.resume(Unit)
                }
            })
    }
}
l

louiscad

04/16/2019, 6:09 AM
Yes, that's expected as cancellation is cooperative. Use
suspenCancellableCoroutine
and unregister the receiver in a finally block, or in cont.invokeOnClose.
a

ansman

04/16/2019, 10:50 AM
That’s not the issue. First of all you cannot unregister the receiver and secondly it shouldn’t matter as withTimeout should still continue and just let the other coroutine be, ignoring it when it (if ever) resumes
Actually, my bad. It was the issue. I’m pretty surprised that’s how it worked
Why does even
suspendCoroutine
exist, why not only have
suspendCancellableCoroutine
l

louiscad

04/16/2019, 4:10 PM
Because cancellation is part of kotlinx.coroutines, and because in some cases, your code is not cancellable (e.g. blocking code).
a

ansman

04/16/2019, 4:57 PM
I thought the only difference was that you could perform more efficient cleanup using the latter
l

louiscad

04/16/2019, 7:00 PM
Try finally works for both, but for the non cancellable, it happens only if your code throws or is done as it will not receive the cancellation signal.