请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

在线程A挂起点返回后的代码怎么执行在线程B中?

suspend fun main() {
    log("main -> start")
    val producer = Coroutine.create<Unit, Int>(Dispatcher()) {
        200.also { log("send", it) }
    }

    val consumer = Coroutine.create<Int, Unit>(Dispatcher()) { param: Int ->
        log("start", param)
    }

    while (producer.isActive && consumer.isActive) {
        val result = producer.resume(Unit)
        log("main -> middle")
        consumer.resume(result)
    }
    log("main -> end")
}

输出:

20:44:44:775 [main] main -> start
20:44:44:853 [Thread-0] send 200
20:44:44:853 [Thread-0] main -> middle
20:44:44:853 [Thread-1] start 200
20:44:44:853 [Thread-1] main -> end

非对称协程,不是在线程A挂起,在线程B执行完返回线程A;那么不是在A挂起点返回后的代码都应该执行在A的线程,现在的运行结果确实在B的线程继续执行,并没有切换回来

正在回答

1回答

非对称协程,跟线程没有什么直接关系。非对称讲的是调用处恢复执行的逻辑,也就是说你通过调用我的 resume 方法来恢复执行我,我执行完以后也会在你调用我的 resume 方法的位置给你返回,但我执行的线程跟你的可能不一样,因此至于在哪个线程恢复执行,跟实现有关系。

1 回复 有任何疑惑可以回复我~
  • 提问者 ak_star #1
    那要恢复主线程,是像下面这样实现么?
    override fun resumeWith(result: Result<R>) {
        .....
        suspend {
            (previousStatus as? Status.Resumed<R>)?.continuation?.resumeWith(result)
        }.startCoroutine(Continuation(MainDispatcher()) { })
    }
    还有其他更好的方法吗?
    回复 有任何疑惑可以回复我~ 2021-01-03 10:57:41
  • bennyhuo 回复 提问者 ak_star #2
    主线程要有事件循环才能调度。这里是用底层的api仿lua的实现,不要跟后面Kotlin的协程框架混了。
    回复 有任何疑惑可以回复我~ 2021-01-03 12:37:43
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信