Как выполнить блокирующий вызов сопрограммы в kotlin и указать поток - PullRequest
2 голосов
/ 14 января 2020

Можно ли выполнить блокирующий вызов сопрограммы (тот, который возвращает значение), а также предоставить поток для выполнения вызова (я не хочу использовать основной поток, который используется по умолчанию)?

Ответы [ 2 ]

3 голосов
/ 14 января 2020

Полагаю, вы ищете asyn c (context):

import kotlinx.coroutines.*

fun someCalc(): Int {
    println(Thread.currentThread().name) // Prints different thread
    Thread.sleep(500L)
    return 42
}

fun main() {
    val result = runBlocking {
        val deferred = async(Dispatchers.Default) {
            someCalc()
        }
        deferred.await()
    }
    println(result)
}

Вы также можете использовать newSingleThreadContext (), чтобы создать контекст, ограниченный одним потоком, и использовать его вместо Dispatchers.Default.

РЕДАКТИРОВАТЬ: Как сказал @Rene, есть лучшее решение:

val result = runBlocking {
        withContext(Dispatchers.Default) {
            someCalc()
        }
    }
1 голос
/ 14 января 2020

Если у вас просто есть поток, который уже запущен, и вы не можете контролировать код, который он выполняет, то вы ничего не можете с этим поделать. Поток должен запускать событие верхнего уровня l oop, чтобы вы могли внедрить код для запуска извне.

Если по какой-либо случайности у вас есть такой вид управления, или вы можете решить, какой Runnable поток будет запущен для начала, вот несколько довольно хакерских кодов, которым удается настроить событие l oop и отправить ему сопрограмму:

val myContextFuture = CompletableFuture<CoroutineContext>()
thread(name = "my-thread") {
    runBlocking {
        myContextFuture.complete(coroutineContext)
        coroutineContext[Job]!!.join()
    }
}
val myContext = myContextFuture.get()

Вот как вы должны запустить сопрограмму на myContext:

val result = withContext(myContext) {
    println("Running on thread ${currentThread().name}")
    3
}
println("Result of the coroutine: $result")

Я бы не рекомендовал использовать этот вид кода в производстве.

...