我正在重写ImageAnalysys.Analyzeranalyze()方法,所以我希望它尽快执行并返回.我有一个我想从analyze()调用的方法,它将操作一些成员变量,并最终想要通知View它有新的东西要显示,但它很长.因此,我希望将该方法排入队列以供执行,但立即返回analyze().

我使用的是GlobalScope.launch { fireAndForgetMethod() },它(显然)按预期工作,但我收到了"微妙的API"警告,帮助弹出窗口表明这不是一个好主意.我已经看到了MainScope().launch {}次,提到了viewModelScope和lifecycleScope.但后来我看到了像How to: Grpc fire and forget async api call in Kotlin这样的文章,这些文章表明,即使只使用火和遗忘也是不受鼓励的.

我最近了解了javascript的asyncawaitPromise体系 struct ,所以我对kotlin的suspend可能会做什么有一个模糊的 idea ,但我认为我需要一个更智能的答案--代码可能seem可以工作,但要狡猾.

  1. 如果我将fireAndForgetMethod()标记为suspend,并从analyze()对其进行正常调用,它是否会立即从调用中返回,这是正确的技术吗?我不需要从方法中得到答案.

  2. 如果不是这样,我应该使用什么范围的launch {}

  3. 有没有其他(批准的)方法可以在不阻塞analyze()的情况下执行较长的操作?(Long方法comesanalyze()开始所需的数据,所以不知何故这就是我需要触发它的地方).如果是一个工作线程,并在线程中设置一个标志来说‘Go!’,那该怎么办?

推荐答案

  1. 您还必须将analyze()标记为suspend方法.然后,对fireAndForgetMethod()的正常调用将等待,直到该方法完成,然后再继续.
  2. 理想情况下,您应该使用coroutineScope(Dispatchers.IO | DEFAULT | MAIN),这取决于您在fireAndForgetMethod()中所做的工作类型.不过,当作用域完成时,它也将等待所有任务完成.即,在它到达"Test"之前,这将首先打印"Async":
runBlocking { // Only needed if your function is not already marked as `suspend`
    coroutineScope {
        launch {
            delay(5000)
            println("Async")
        }
    }
}
println("Test")
  1. 您可以使用线程.如果您的系统/框架(例如,Android、Spring等)支持后台工作程序,您可以使用它.

如果您真的希望函数在后台执行,而没有任何可以等待它的作用域,那么使用GlobalScope就可以了.

Kotlin相关问答推荐

如何创建继承抽象的匿名对象的新实例?

如何在Jetpack Compose中的列中渲染图像

Kotlin -从列表中获取特定过滤器的唯一列表值

某些公共函数显然不能在类实例上访问;Klaxon示例

Kotlin编译器如何决定是否可以在任何给定点调用Suspend方法?

kotlin 父类具有依赖于抽象变量的变量

根据字符串值动态过滤数组列表 - kotlin

在 Kotlin 协程中切换 IO 和 UI 的正确方法是什么?

parallelStream()和asSequence().asStream().parallel()之间的区别

异常传播如何在 CoroutineScope.async 上工作?

如何在 kotlin 中通过反射设置委托属性值?

如何在 Android 的 Fragment 中使用 setUserVisibleHint

AIDL 中的 Parcelize 注释:Incompatible types: Object cannot be converted to MyCustomObject

如何在使用 Gradle 的 AppEngine 项目中使用 Kotlin

Kotlin:使用Gradle进行增量编译

Android插件2.2.0-alpha1无法使用Kotlin编译

如何在使用Koin DI的活动之间共享同一个ViewModel实例?

Kotlin - computed var 属性的用处?

在Kotlin中将列表转换为对的惯用方法

如何在 firebase 数据库中使用 kotlin 协程