Korlin coruntines не будет выполняться при запуске и обратном вызове - PullRequest
3 голосов
/ 01 декабря 2019

Мне показалось, что я достаточно хорошо знаком с сопрограммами Котлина, пока не получил этот код.

От 1 до 8 все напечатаны, кроме 2:

import kotlinx.coroutines.*
import java.lang.Runnable
import java.lang.Thread.sleep
import kotlin.concurrent.thread

fun main() {
    runBlocking {
        Client.createAccount()
        delay(1000)
    }
}

object Client: CoroutineScope {
    override val coroutineContext = newSingleThreadContext("Client")

    fun createAccount() = launch {
        Client2.init(Runnable {
            println('1')
            launch {
                println('2')
            }
            ok()
            ok2()
        })

        println('7')
        launch {
            println('8')
        }
    }

    fun ok() {
        println('3')
        launch {
            println('4')
        }
    }

    fun ok2() = launch {
        println('5')
        launch {
            println('6')
        }
    }
}

object Client2 {

    fun init(runnable: Runnable) = thread {
        sleep(100)
        runnable.run()
    }
}

Результат:

7
8
1
3
4
5
6

Сопрограмма в обратном вызове никогда не будет вызвана. Почему? И если я уберу launch в createAccount(), все от 1 до 8 будут напечатаны. Также, если я использую GlobalScope.launch { println('2') } вместо launch { println('2') }, я могу также напечатать 2.

1 Ответ

0 голосов
/ 02 декабря 2019

launch публикует Runnable в обработчике, поэтому его выполнение кода не является немедленным. launch (Dispatchers.Main, CoroutineStart.UNDISPATCHED) немедленно выполнит свое лямбда-выражение в текущем потоке.

измените диспетчер на текущий, который вы используете, измените ланч из потока на

launch (coroutineContext, CoroutineStart.UNDISPATCHED)

.

fun createAccount() = launch {

    Client2.init(Runnable {
        println('1')
        launch (coroutineContext, CoroutineStart.UNDISPATCHED){
            println('2')
        }
        ok()
        ok2()
    })

    println('7')
    launch {
        println('8')
    }
}

вывод:

7
8
1
2
3
4
5
6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...