我正在启动协程,并且希望它在恢复执行主线程之前完成。
我的简化代码如下:
fun hello() {
for (i in 0..100) {
println("hello")
}
}
fun main(args: Array<String>) {
val job = GlobalScope.launch { hello() } //launch parallel
GlobalScope.launch { job.join() } //try to wait for job to finish
print("done")
}
问题在于,由于job.join()
必须位于协程中,因此执行的主行被推迟为“完成”,因此输出如下所示:
donehello
hello
hello
hello
我想等待作业完成,就像在Go中使用sync.WaitGroup
一样。所以我的输出将确定地看起来像这样:
hello
hello
hello
hello
...
done
我如何做到这一点?
答案 0 :(得分:2)
实际上,对于您的样本,job.join()
是确保此时等待直到给定作业完成的方式。不幸的是,您再次将其打包在GlobalScope.launch
中,这只是将等待的内容放入了后台线程。因此,它比您预期的更早到达了done
,并且在我的机器上它甚至没有打印任何hello
(但可以)。
我假设您使用launch
是因为join
只能从协程或其他暂停函数调用?对于您的示例,只需将suspend
添加到main
就足够了,例如:
suspend fun main() {
val job = GlobalScope.launch { hello() }
job.join()
print("done")
}
或者您可以使用runBlocking
并将main
包裹起来,例如:
fun main() = runBlocking {
val job = launch { hello() }
job.join()
print("done")
}
现在免责声明...您可能希望在继续之前(如果您尚未这样做的话)查阅以下资源:
答案 1 :(得分:0)
为什么不在协同程序中打印消息?您可以通过执行以下操作来实现所需的目标:
GlobalScope.launch {
hello()
print("done")
}
或者您可以运行协程并阻塞直到完成,即使这违反了协程的目的:
runBlocking { GlobalScope.launch { hello() }
print("done")