【问题标题】:How do I best handle coroutine concurrency?如何最好地处理协程并发?
【发布时间】:2021-06-16 16:43:30
【问题描述】:

我正在开发一个带有 recyclerview 列表(数据位于 Room db 中)和谷歌地图的项目。在 googlemap 上,绘制了从 Room db 收集的不同类型的标记,并且在地图上绘制了列表中完成的操作(即更改 Marker.visibility、颜色等),所有这些都非常有效,直到。 ..

用户在列表中执行操作(更新房间数据库),livedata 观察并启动进程(这可能很耗时),我通过调用lifeCycleScope.launchWhenStarted 解决了这个问题,并在其中使用了withContext(Dispatchers.Default)耗时的部分,再次使用withContext(Dispatchers.Main) 将每个更改移植到googleMap。这很好用。

由于withContext(Dispathcers.Default) 继续工作,实际观察者运行到最后,可能会触发新的 livedata observables。

第二个 observable 触发可能会在协程部分完成之前开始,我可能会遇到并发错误。是否有一种“理智”的方式来“停止”withContext(Dispatchers.Default)(某种“waitFor”条件)内的第二次尝试(或所有后续尝试)的处理,并让它们在正在进行的过程完成时开始?

I.E.代码:

myLiveData.observe(viewLifeCycleOwner){myData->
  
  lifeCycleScope.launchWhenStarted{
    //do some context main work
    withContext(Dispatchers.Default){
      //Do some heavy work pt 1
      withContext(Dispatchers.Main) {/*Update views*/}
      //Do some heavy work pt 2
      withContext(Dispatchers.Main) {/*Update views2*/} 
    } 
  }
}

【问题讨论】:

  • 您是否考虑过使用协程核心库中的互斥锁? kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/…
  • @PietroScarampella 你有什么好的例子说明 Mutex 如何处理对该观察者的后续调用,它们可以优雅地排队吗?
  • ...我的意思是:当两个或多个后续尝试时,当互斥锁被解锁时,他们中的谁会做出反应,只有一个,或两者,或者他们以某种方式排队。
  • 如果你不关心后续调用的顺序,互斥锁是一个不错的选择,因为它会被第一个请求它的任务锁定。但是,如果顺序对您很重要,那么请使用 actor,actor 是原子的,并且您发送给它的消息将按顺序执行:kotlinlang.org/docs/…
  • 您可以使用 Flow 和 collectLatest 运算符来代替 LiveData,它会在新值到达时立即取消正在进行的操作。

标签: android kotlin concurrency kotlin-coroutines


【解决方案1】:

由于顺序对您很重要,我建议使用actor 来处理如here 所述的顺序计算

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-03
    • 2010-11-24
    • 2013-06-13
    • 2014-01-28
    • 2021-02-03
    • 2013-06-19
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多