Kotlin 无法在协同程序内创建局部变量
我对Kotlin协同程序这个话题还不熟悉,有一个问题完全阻碍了我使用它们。我有以下代码要与协同程序一起运行:Kotlin 无法在协同程序内创建局部变量,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,我对Kotlin协同程序这个话题还不熟悉,有一个问题完全阻碍了我使用它们。我有以下代码要与协同程序一起运行: runBlocking { for (i in 0 until args[1].toInt()) { GlobalScope.launch { OuterObject().run() } } 我的OuterObject类在run()方法中有以下代码: 所有协同路由都从循环开始,但只到达“检查点0”。尝试创建innerObject后
runBlocking {
for (i in 0 until args[1].toInt()) {
GlobalScope.launch {
OuterObject().run()
}
}
我的OuterObject类在run()方法中有以下代码:
所有协同路由都从循环开始,但只到达“检查点0”。尝试创建innerObject后,没有日志消息或任何其他操作
我尝试的第一件事是创建另一个对象,但问题似乎是一般性的,不依赖于对象的类。我已经尝试了DateTime()、Gson()和其他一些方法——每次协同程序都会在此时停止。我还尝试将异常处理添加到协同程序中,但没有捕获到异常-协同程序只是静静地停止
这背后的原因是什么?我如何避免
kotlinx协程核心版本:1.2.2
更新1:
我已经检查了一个基本类型赋值,它是有效的。控制台日志中同时显示“检查点0”和“检查点1”。这个问题只适用于复杂类型
override fun run() {
...
logger.info(){ "Checkpoint 0" }
var test = 1
logger.info(){ "Checkpoint 1" }
...
}
更新2:
@格拉德和山姆,你说得对。@roman elizarov的文章也帮了我的忙:。从GlobalScope调用“launch”是错误的-它与runBlocking作用域无关
我已按以下方式修改了代码:
runBlocking {(0 until args[1].toInt()).forEach {
launch(Dispatchers.Default) {
OuterObject().run()
}
}
我在以这种方式运行代码时遇到了一些进一步的问题,但它们是由于非最佳并发性造成的。启动了一个新的协同程序。但你不是在等它完成。相反,请考虑:
runBlocking{
(0到args[1].toInt()).forEach{
发射{
OuterObject().run()
}
}
}
这样,在所有启动的作业完成之前,
runBlocking
不会返回。(删除GlobalScope时归功于@Sam。)谢谢您的回复!我试过你的建议,但不幸的是结果是一样的。据我所知,joinAll一般不需要。runBlocking在自己的作用域中启动新的协同路由,它将自动等待所有启动的作业完成。@AgitarunBlocking
将等待在自己的作用域中启动作业,但您正在不相关的GlobalScope
中启动作业。您可以将GlobalScope.launch
替换为launch
。我们可能需要查看内部/外部对象中发生的情况,以便提供更多帮助。@Sam,确实,这就是原因。我通过删除GlobalScope并指定Dispatchers.Default作为“launch”(参见文章中的最终代码更新)实现了这个结果。伙计们,非常感谢你们的帮助。
runBlocking {(0 until args[1].toInt()).forEach {
launch(Dispatchers.Default) {
OuterObject().run()
}
}