【问题标题】:Handle file operations with coroutines使用协程处理文件操作
【发布时间】:2018-11-19 16:10:53
【问题描述】:

目前我正在 Kotlin 中为 Android 开发一个持久性库。在我的代码中,我必须处理出于性能原因我希望异步执行的文件操作(读取、写入等)。我认为我可以使用 Kotlin 1.3 的新协程功能来做到这一点

GlobalScope.launch {
    writeFileAsync(file, bytes)
}

private suspend fun writeFileAsync(file: File, bytes: ByteArray) {
    try {
        file.writeBytes(bytes)
    }  catch (e: Exception) {
        throw PersistenceException(e)
    }
}

假设我处于这样一种情况,即用户更改了一个对象,该对象现在使用上面的代码持久化,并且他在协程完成之前 关闭了应用程序。当然我不想因为数据丢失而停止协程,但是这里可以吗,还是我泄露了协程?

我也不确定如何在协程运行时阻止对该文件的所有其他操作(可能来自其他线程或进程),所以如果您对此也有想法,请告诉我。

【问题讨论】:

    标签: android kotlin kotlinx.coroutines


    【解决方案1】:

    首先,您在协程中执行的代码并没有更高的性能。它的性能可能甚至更低。但它更具并发性。

    其次,如果用户终止应用程序,它的所有线程都将关闭。由于协程基于线程池,它们也会停止。如果您想让某些东西在后台继续工作,请改用 Service 之类的东西。

    第三,如果你想获得一个文件的锁,使用FileLock

    【讨论】:

    • 感谢FileLock 的提示。我阅读了文档,发现这一段令人困惑:文件锁是代表整个 Java 虚拟机持有的。它们不适合控制同一虚拟机中的多个线程对文件的访问。这对我的用例来说不是问题吗?
    【解决方案2】:

    当应用程序可以终止时,使用WorkManager 在后台执行您的工作。

    【讨论】:

      【解决方案3】:

      你写的代码根本没有使用协程挂起。它只是将一段代码提交到一些默认的公共线程池,这是你不需要协程的。你也可以写

      ForkJoinPool.commonPool().submit {
          file.writeBytes(bytes)
      }
      

      而且你不需要协程依赖。

      但是,如果您想等待 IO 操作完成并跟随它进行一些 GUI 操作,那么协程将帮助您。你可以写

      this.launch {
          withContext(Dispatchers.IO) {
              file.writeBytes(bytes)
          }
          updateGui()
      }
      

      但是,这不会阻止用户在操作进行时关闭应用程序。这是另一个级别的挑战,要实现它,您必须更深入地将操作与 Activity 分离,WorkManager 似乎是最现代的选择。

      【讨论】:

      • 或者我们可以从 onStop 中的后台服务开始(并且可以在绑定到它的活动被销毁时将其转为前台)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 2022-12-20
      • 1970-01-01
      • 2011-09-30
      • 2018-09-22
      • 1970-01-01
      相关资源
      最近更新 更多