- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 Kotlin/Coroutines 的新手,所以希望我只是错过了一些东西/没有完全理解如何为我试图解决的问题构建我的代码。
本质上,我正在获取一个字符串列表,对于列表中的每个项目,我想将其发送到另一个方法来完成工作(进行网络调用并根据响应返回数据)。 (编辑:)我希望所有调用同时启动,并阻止直到所有调用完成/响应被执行,然后返回一个包含每个响应信息的新列表。
我可能还没有完全理解何时使用启动/异步,但我尝试遵循启动(使用 joinAll
)和异步(使用 await
)。
fun processData(lstInputs: List<String>): List<response> {
val lstOfReturnData = mutableListOf<response>()
runBlocking {
withContext(Dispatchers.IO) {
val jobs = List(lstInputs.size) {
launch {
lstOfReturnData.add(networkCallToGetData(lstInputs[it]))
}
}
jobs.joinAll()
}
}
return lstofReturnData
我期望发生的是,如果我的lstInputs
大小为120,当所有作业加入后,我的lstOfReturnData
尺寸也应为 120。
实际发生的是不一致的结果。我将运行它一次,我在最终列表中得到 118,再次运行它,它是 120,再次运行它,它是 117,等等。在 networkCallToGetData()
中。方法中,我正在处理任何异常,至少为每个请求返回一些内容,无论网络调用是否失败。
任何人都可以帮助解释为什么我得到不一致的结果,以及我需要做什么来确保我正确阻止并且在继续之前所有作业都已加入?
最佳答案
mutableListOf()
创建一个 ArrayList
,它不是线程安全的。
尝试使用 ConcurrentLinkedQueue
代替。
另外,您使用 Kotlin/Kotlinx.coroutine 的稳定版本(而不是旧的实验版)吗?在稳定版本中,随着结构化并发的引入,不再需要编写jobs.joinAll
。 launch
是 runBlocking
的扩展函数,它将在 runBlocking
范围和 runBlocking
范围内启动新的协程将自动等待所有启动的作业完成。所以上面的代码可以缩短为
val lstOfReturnData = ConcurrentLinkedQueue<response>()
runBlocking {
lstInputs.forEach {
launch(Dispatches.IO) {
lstOfReturnData.add(networkCallToGetData(it))
}
}
}
return lstOfReturnData
关于Kotlin 协程 - 如何阻止等待/加入所有作业?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54719864/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!