fun main() {
println("Start of program")
GlobalScope.launch{
println("Starting coroutine")
val result = someOperation()
println("Coroutine Running thread is: ${Thread.currentThread().name}")
println("Coroutine completed with result: $result")
println("End of the coroutine function")
}
println("End of program")
}
suspend fun someOperation(): String { //This is a coroutine now (Due to suspend modifier).
delay(3000) // long-running operation
return "Operation performed successfully"
}
有人能解释一下为什么我的输出是这个吗?
Start of program
End of program
而预期产出是:
Start of program
Starting coroutine
Coroutine Running thread is: DefaultDispatcher-worker-1
Coroutine completed with result: Operation performed successfully
End of the coroutine function
End of program
如果协程应该在后台线程上运行,为什么在上面的例子中协程甚至没有被调用呢?
据我所知,主函数应该首先被触发,它应该产生协程(最终线程),至少在完成主函数之后,程序应该在退出之前给予协程完成的机会。
**P.S:**我在协程和异步编程方面有很大的困难。如果有人有同样的好资源,请分享它将会很有帮助。
2条答案
按热度按时间owfi6suc1#
启动协程会将其排队以开始异步运行。当它开始运行时,主函数会同步继续。当它返回时,应用已完成,因此它会终止。如果您希望应用保持打开状态以等待协程完成,您需要在
launch
返回的作业上调用join()
。要在main
中执行此操作,您需要将main
标记为suspend函数,或者将其所有代码包含在runBlocking { }
中,以便在其中调用suspend函数。或者,如果您使用
runBlocking
,则可以直接启动子协程而不使用GlobslScope,这样就不必在其上调用join()
。runBlocking
会自动等待其所有子协程完成。snz8szmq2#
如果您查看GlobalScope的文档,它明确指出:
在GlobalScope中启动的活动协程并不保持进程的活动状态。它们就像守护进程线程。
但这并不是
GlobalScope
所特有的。协程通常不会让进程保持活动状态。线程可以。协程是围绕结构化并发的概念设计的,其中任务由较小的子任务组成,并等待它们完成。如果我们启动了一个协程,但我们没有以任何方式观察它,它就不是一个更大任务的一部分,等等。那就好像我们不再需要这个协程了,这类似于分配一个对象,但不存储对它的引用。使用协程的常见模式是在
main()
中调用runBlocking()
,并将其作为“根”协程,它是应用程序中运行的所有/大多数协程的父级。这样我们可以很容易地确保不会泄漏任何后台任务,我们可以取消整个应用程序的所有任务,等等。