【问题标题】:How to cancel/unsubscribe from coroutines Flow如何取消/取消订阅协程流程
【发布时间】:2020-04-28 00:52:06
【问题描述】:

我在尝试过早取消流程时发现了一个奇怪的行为。看看下面的例子。

这是一个发出整数值的简单流程

  private fun createFlow() = flow {
        repeat(10000) {
            emit(it)
        }
    }

然后我使用此代码调用createFlow 函数

  CoroutineScope(Dispatchers.Main).launch {
            createFlow().collect {

                Log.i("Main", "$it isActive $isActive")
                if (it == 2) {
                    cancel()
                }
            }
        }

这是打印出来的

0 isActive true
1 isActive true
2 isActive true
3 isActive false
4 isActive false
etc...etc

现在我希望流一旦达到 2 的值就应该停止发射整数,但实际上它会将 isActive 标志切换为 false 并继续发射而不停止。

当我在排放之间添加延迟时,流程的行为与我预期的一样。

private fun createFlow() = flow {
    repeat(10000) {
        delay(500) //add a delay
        emit(it)
    }
}

这是再次调用流程后打印的内容(这是预期的行为)。

0 isActive true
1 isActive true
2 isActive true

如何在不增加延迟的情况下完全取消指定值的流量发射?

【问题讨论】:

标签: android kotlin-coroutines kotlinx.coroutines.flow


【解决方案1】:

我想在 1.3.7 version 中添加流生成器的排放现在检查取消状态并且可以正确取消。所以有问题的代码将按预期工作

【讨论】:

    【解决方案2】:

    我最近想出了这个

    它似乎只有在到达暂停点并且在您发出的代码中没有这样的点时才会真正取消

    要解决这个问题,可以在发射之间添加 yield() 或其他一些暂停函数,例如延迟 (100)

    【讨论】:

      【解决方案3】:

      我在this 相关问题中遇到了解决方法

      我已将项目中的每个 collect 替换为 safeCollect 函数:

      /**
       * Only proceed with the given action if the coroutine has not been cancelled.
       * Necessary because Flow.collect receives items even after coroutine was cancelled
       * https://github.com/Kotlin/kotlinx.coroutines/issues/1265
       */
      suspend inline fun <T> Flow<T>.safeCollect(crossinline action: suspend (T) -> Unit) {
        collect {
          coroutineContext.ensureActive()
          action(it)
        }
      }
      

      【讨论】:

      • 我相信你可以将.cancellable() 添加到你的Flow 中: > 这个操作符为.onEach { currentCoroutineContext().ensureActive() } 提供了一个快捷方式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 2020-04-07
      • 2022-01-19
      • 2012-03-14
      • 2013-04-01
      • 1970-01-01
      相关资源
      最近更新 更多