gpt4 book ai didi

kotlin - 我什么时候应该暂停我的正常功能?

转载 作者:行者123 更新时间:2023-12-02 05:46:58 24 4
gpt4 key购买 nike

借助最新稳定版本的 kotlin 协程,我尝试使用它来实现我的应用程序的功能之一。但是,我有点困惑。

基本上,我有一个函数可以对项目列表进行一些工作。这大约需要 700-1000 毫秒。

fun processList(list : ArrayList<String>) : ArrayList<Info> {

val result = mutableListOf<Info>()

for (item in list) {
// Process list item
// Each list item takes about ~ 15-20ms
result.add(info) // add processed info to result
}

return result // return result
}

现在,我想在不阻塞主线程的情况下实现它。所以我在启动 block 内启动这个函数,这样它就不会阻塞主线程。

coroutineScope.launch(Dispatchers.Main) {
val result = processList(list)
}

效果很好。

但是,我尝试将该函数设置为挂起函数,以确保它永远不会阻塞主线程。实际上,函数内部没有启动任何其他协程。还尝试在单独的协程中处理每个列表项,然后将它们全部连接起来以使其实际使用子协程。但是循环内的 block 使用同步方法调用。因此,将其设为异步并行是没有意义的。所以我最终有一个这样的挂起函数:

suspend fun processList(list : ArrayList<String>) : ArrayList<Info> = coroutineScope {

val result = mutableListOf<Info>()

for (item in list) {
// Process list item
// Each list item takes about ~ 15-20ms
result.add(info) // add processed info to result
}

return result // return result
}

开头只有一个挂起修饰符,方法 block 用 coroutineScope { } 包裹。

这还有关系吗?哪一个更好?如果函数使用协程,我是否应该只将其设置为挂起函数,或者长时间运行的函数也应该标记为挂起函数?

我很困惑。我看过最近所有关于协程的讨论,但无法弄清楚这一点。

谁能帮我理解这个?

更新:

所以我最终得到了这样的函数。只是为了确保该函数永远不会在主线程上调用。并且调用函数不必记住需要在后台线程上调用的所有地方。通过这种方式,我可以使调用函数的事物变得抽象:只需执行告诉的操作即可,我不在乎您想在哪里处理这些事物。只需处理并给我结果即可。 因此,函数会自行处理需要运行的位置,而不是调用函数。

suspend fun processList(list : ArrayList<String>) : ArrayList<Info> = coroutineScope {

val result = mutableListOf<Info>()

launch(Dispatchers.Default) {
for (item in list) {
// Process list item
// Each list item takes about ~ 15-20ms
result.add(info) // add processed info to result
}
}.join() // wait for the task to complete on the background thread

return result // return result
}

这是正确的方法吗?

最佳答案

您希望将 CPU 密集型计算卸载到后台线程,这样 GUI 线程就不会被阻塞。您不必声明任何挂起函数即可实现此目的。这就是您所需要的:

myActivity.launch {
val processedList = withContext(Default) { processList(list) }
... use processedList, you're on the GUI thread here ...
}

上面假设您已将 CoroutineScope 接口(interface)正确添加到您的 Activity,如其 documentation 中所述。 .

更好的做法是将 withContext 插入 processList 的定义中,这样您就不会犯在主线程上运行它的错误。声明如下:

suspend fun processList(list: List<String>): List<Info> = withContext(Default) {
list.map { it.toInfo() }
}

这假设您已将字符串到信息逻辑放入

fun String.toInfo(): Info = // whatever it takes

关于kotlin - 我什么时候应该暂停我的正常功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53228011/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com