主要思想是拥有一个非挂起的函数runInBackgroundAndUseInCallerThread(callback: (SomeModel) -> Unit),该函数在后台(另一个线程)异步运行某些工作,并且在工作完成之后-在调用者线程(启动runInBackgroundAndUseInCallerThread的线程)中运行回调。

下面我写了一个示例代码,但是我不确定它的正确性以及是否可能。使用println("1/2/3/..."),我标记了所需的 call 顺序。getDispatcherFromCurrentThread-如果可以实现此功能,则可以使用解决方案,但是我不知道如何实现它,这样做是正确的。

因此,请不要将其视为唯一的解决方案。

import kotlinx.coroutines.*
import kotlin.concurrent.thread

fun main() {
    println("1")
    runInBackgroundAndUseInCallerThread {
        println("4")
        println("Hello ${it.someField} from ${Thread.currentThread().name}") // should be "Hello TestField from main"
    }
    println("2")
    thread(name = "Second thread") {
        runInBackgroundAndUseInCallerThread {
            println("5")
            println("Hello ${it.someField} from ${Thread.currentThread().name}") // should be "Hello TestField from Second thread"
        }
    }
    println("3")
    Thread.sleep(3000)
    println("6")
}

fun runInBackgroundAndUseInCallerThread(callback: (SomeModel) -> Unit) {
    val dispatcherFromCallerThread: CoroutineDispatcher = getDispatcherFromCurrentThread()
    CoroutineScope(Dispatchers.IO).launch {
        val result: SomeModel = getModelResult()
        launch(dispatcherFromCallerThread) { callback(result) }
    }
}

data class SomeModel(val someField: String)

suspend fun getModelResult(): SomeModel {
    delay(1000)
    return SomeModel("TestField")
}

fun getDispatcherFromCurrentThread(): CoroutineDispatcher {
    // TODO: Create dispatcher from current thread... How to do that?
}

最佳答案

除非线程被设计成可以用作调度程序,否则没有一种通用的方法可以使它成为调度程序。
想到的唯一方法是runBlocking是可重入的,并会在现有线程中创建一个事件循环,但是它将阻止所有非协程代码在该线程上执行,直到完成。

最终看起来像:

fun runInBackgroundAndUseInCallerThread(callback: (SomeModel) -> Unit) {
    callback(runBlocking(Dispatchers.IO) {
        getModelResult()
    })
}

关于kotlin - Kotlin协程-如何在后台运行并在调用方线程中使用结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59486388/

10-11 22:43
查看更多