【问题标题】:Method Declaration kotlin async{}方法声明 kotlin async{}
【发布时间】:2018-06-19 10:26:10
【问题描述】:

我想知道什么是长时间运行任务的正确声明。

suspend fun methodName(image: Bitmap?): String? = async {
   // heavy task
}.await()

fun methodName(image: Bitmap?): String? {
   //heavyTask
}

在代码中使用

async{
   methodName()
}.await()

第一个限制总是在后台线程上执行繁重的操作。所以,它是安全的(在某种程度上它将在后台线程上运行,因此新的开发人员一定会在可挂起的构造中使用它)。

哪种方法更好?

【问题讨论】:

    标签: android multithreading kotlin coroutine kotlin-android-extensions


    【解决方案1】:

    我相信suspend 关键字是对用户的强烈警告,以防止在敏感线程中使用特定功能。但情况可能并非总是如此。正如coroutines documentation 中所说:

    如果相关调用的结果已经可用,图书馆可以决定继续进行而不暂停

    如果“繁重的任务”是直截了当的。 (例如:复制文件)我个人只是在函数中添加挂起而不创建协程。用户完全负责调用此函数的位置。

    @Throws(IOException::class)
    suspend fun copy(input: File, output: File) {
       //copying
    }
    

    如果“繁重的任务”是由其他suspend函数组成的。警告一般是函数参数中的couroutineContext。它在内部使用withContext() 之类的函数。

    withContext : 挂​​起直到完成,并返回结果

    @Throws(IOException::class)
    suspend fun copyMultiple(context: CoroutineContext, pairFiles: List<Pair<File, File>>) {
        pairFiles.forEach { (input, output) ->
            withContext(context) { 
                copy(input, output)
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      考虑在您的情况下使用withContext() 而不是async{}.await()

      关于你的问题,恕我直言,最好使用这样的结构:

      suspend fun methodName(image: Bitmap?): String? = withContext(CommonPool) {
         // heavy task
      }
      

      【讨论】:

      • 问题是,我是否应该控制“在任何线程上执行非 UI 依赖的繁重任务给开发人员”还是不应该。
      • @Viking93 取决于您要做什么。如果您正在创建库的公共 API,最好将线程工作委托给开发人员,因为您不应该强迫其他开发人员使用 Kotlin、协程等。否则,如果此代码仅在您的团队中使用,我的示例就是您需要,因为它使用了您的技术堆栈并有助于避免可能的线程问题(您只能指定一次协程上下文)。
      猜你喜欢
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      相关资源
      最近更新 更多