Сопрограммы, обработка исключений и withTimeout. Не могу обернуть голову вокруг этой комбинации - PullRequest
4 голосов
/ 15 апреля 2020
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlin.system.measureTimeMillis

fun time() = System.currentTimeMillis()

fun main(args: Array<String>) {
    runBlocking {
        repeat(5) {
            try {
                println("${time()} withTimeout before")
                withTimeout(1L) {
                    try {
                        delay(200L)
                    } catch (e: Exception) {
                        println("${time()} withTimeout exception " + e.localizedMessage)
                    }
                }
                println("${time()} withTimeout done")
            } catch (e: Exception) {
                println("${time()} exception " + e.localizedMessage)
            }
            println("${time()} -----")
        }
    }
}

Это дает мне вывод:

1586923684774 withTimeout before
1586923684788 withTimeout exception Timed out waiting for 1 ms
1586923684789 withTimeout done
1586923684789 -----
1586923684789 withTimeout before
1586923684790 withTimeout exception Timed out waiting for 1 ms
1586923684791 exception Timed out waiting for 1 ms
1586923684791 -----
1586923684791 withTimeout before
1586923684792 withTimeout exception Timed out waiting for 1 ms
1586923684792 exception Timed out waiting for 1 ms
1586923684792 -----
1586923684792 withTimeout before
1586923684794 withTimeout exception Timed out waiting for 1 ms
1586923684794 exception Timed out waiting for 1 ms
1586923684794 -----
1586923684794 withTimeout before
1586923684795 withTimeout exception Timed out waiting for 1 ms
1586923684795 exception Timed out waiting for 1 ms
1586923684795 -----

При первом выводе l oop, withTimeout done.

Вопрос 1: Почему только на первой итерации?

Вопрос 2: Если я изменю время ожидания на withTimeout от 1л до 10л не печатается. Вместо этого исключение распространяется на внешний try / catch, как на следующих итерациях (см. Ниже). Почему?

1586923727317 withTimeout before
1586923727333 withTimeout exception Timed out waiting for 10 ms
1586923727334 exception Timed out waiting for 10 ms
1586923727334 -----
1586923727334 withTimeout before
1586923727347 withTimeout exception Timed out waiting for 10 ms
1586923727347 exception Timed out waiting for 10 ms
1586923727347 -----
1586923727347 withTimeout before
1586923727360 withTimeout exception Timed out waiting for 10 ms
1586923727360 exception Timed out waiting for 10 ms
1586923727360 -----
1586923727360 withTimeout before
1586923727370 withTimeout exception Timed out waiting for 10 ms
1586923727371 exception Timed out waiting for 10 ms
1586923727371 -----
1586923727371 withTimeout before
1586923727382 withTimeout exception Timed out waiting for 10 ms
1586923727382 exception Timed out waiting for 10 ms
1586923727382 -----

Вопрос 3: Почему, хотя исключение перехватывается внутри блока try / catch в withTimeout(), оно распространяется к внешнему блоку try / catch?

Я ценю и заранее благодарю за помощь.

...