https://kotlinlang.org logo
#coroutines
Title
# coroutines
f

farzad

07/14/2019, 11:16 AM
If I run this:
Copy code
import kotlinx.coroutines.*

fun main(args: Array<String>) {
    runBlocking {
        withTimeout(1300L) {
            repeat(1000) { i ->
                 println("I'm sleeping $i ...")
                delay(500L)
            }
        }
    }
}
then I'll get this output:
Copy code
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
Exception in thread "main" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1300 ms
 at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException (Timeout.kt:126) 
 at kotlinx.coroutines.TimeoutCoroutine.run (Timeout.kt:92) 
 at kotlinx.coroutines.EventLoopImplBase$DelayedRunnableTask.run (EventLoop.kt:307) 
 at kotlinx.coroutines.EventLoopImplBase.processNextEvent (EventLoop.kt:116) 
 at kotlinx.coroutines.DefaultExecutor.run (DefaultExecutor.kt:68) 
 at java.lang.Thread.run (Thread.java:745)
But if I run this one:
Copy code
import kotlinx.coroutines.*

fun main(args: Array<String>) {
    runBlocking {
		launch{
            withTimeout(1300L) {
                repeat(1000) { i ->
                    println("I'm sleeping $i ...")
                    delay(500L)
                }
            }
        }
    }
}
I'll get another output:
Copy code
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
why the second one doesnot throw exception?
s

streetsofboston

07/14/2019, 1:48 PM
The
TimeoutCancellationException
is a sub-class of
CancellationException
. CancellationExceptions that are thrown inside a Coroutine that was `launch`ed do not propogate to any exception-handler, not to a CoroutineExceptionHandler and not to the Thread's Uncaught Exception Handler (the last one was called in your first example). Here is a modified version of your 2nd example, where the CancellationException is wrapped in a plain RuntimeException (something that is not a CancellationException). You'll see the stacktrace log again:
Copy code
import kotlinx.coroutines.*

fun main(args: Array<String>) {
    runBlocking {
        launch {
            try {
                withTimeout(1300L) {
                    repeat(1000) { i ->
                        println("I'm sleeping $i ...")
                        delay(500L)
                    }
                }
            } catch (t: CancellationException) { 
                throw RuntimeException(t)
            }
        }
    }
}
👍 1
g

gildor

07/14/2019, 2:54 PM
The main thing why launch and runBlocking work differently is because runBlocking returns value, but because scope is cancelled, nothing to return and it throws cancellation exception, for launch it just cancel coroutine
👍 1
f

farzad

07/15/2019, 5:13 AM
Thanks guys. 👍
2 Views