Приостановить функциональные блоки основной поток - PullRequest
1 голос
/ 05 марта 2019

Мне трудно понять сопрограммы. Это очень простая настройка. И longComputation, и delay являются функциями приостановки. Первый блокирует основной поток, второй - нет. Почему?

CoroutineScope(Dispatchers.Main).launch {
    val result = longComputation() // Blocks
    delay(10_000) // Doesn't block
}

1 Ответ

3 голосов
/ 05 марта 2019

Это зависит.Что делает longComputation?Когда вы помечаете функцию как suspend, это не означает, что вы не можете включить в нее блокирующий код.Например, посмотрите на это:

suspend fun blockingSuspendFunction(){
    BigInteger(1500, Random()).nextProbablePrime()
}

Код внутри функции приостановки, очевидно, использует процессор и блокирует вызывающую программу. По соглашению этого делать не следует, поскольку если вы вызываете функцию приостановки, вы ожидаете ее , а не блокирования потока:

Соглашение: функции приостановки не блокируют поток вызывающего.(https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761)

Чтобы заставить такую ​​функцию «вести себя как приостанавливающая функция», необходимо передать блокировку другому рабочему потоку, что (по рекомендации) должно произойти с withContext:

suspend fun blockingSuspendFunction() = withContext(Dispatchers.Default) {
    BigInteger.probablePrime(2048, Random())
}
...