Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 无法在协同程序内创建局部变量_Kotlin_Kotlin Coroutines - Fatal编程技术网

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后

我对Kotlin协同程序这个话题还不熟悉,有一个问题完全阻碍了我使用它们。我有以下代码要与协同程序一起运行:

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在自己的作用域中启动新的协同路由,它将自动等待所有启动的作业完成。@Agita
runBlocking
将等待在自己的作用域中启动作业,但您正在不相关的
GlobalScope
中启动作业。您可以将
GlobalScope.launch
替换为
launch
。我们可能需要查看内部/外部对象中发生的情况,以便提供更多帮助。@Sam,确实,这就是原因。我通过删除GlobalScope并指定Dispatchers.Default作为“launch”(参见文章中的最终代码更新)实现了这个结果。伙计们,非常感谢你们的帮助。
runBlocking {(0 until args[1].toInt()).forEach {
    launch(Dispatchers.Default) {
        OuterObject().run()
    }
}