【问题标题】:JobCancellationException StandaloneCoroutine was cancelledJobCancellationException StandaloneCoroutine 被取消
【发布时间】:2020-06-29 16:17:51
【问题描述】:

由于我们使用的是 Coroutines(使用 1.3.5),我们遇到了很多崩溃:JobCancellationException - StandaloneCoroutine 被取消

我阅读了很多关于这些问题的帖子,并在生产中尝试了很多解决方案,但总是发生崩溃。

在我们所有的视图模型中,我们都在使用 viewmodelscope,所以没关系。

但是在我们的数据层中,我们需要启动一个跟踪事件,它是fire and forget 任务。在第一步中,我们使用了GlobalScope.launch。我在想 CancelletationException 是由于这个全局范围造成的,所以我删除了它并使用 SupervisorJobCoroutineExceptionHandler 在数据层中创建了一个扩展:

private val appScope = CoroutineScope(Dispatchers.Default + SupervisorJob())
private val coroutineExceptionHandler by lazy { CoroutineExceptionHandler { _, throwable -> logw("Error occurred inside Coroutine.", throwable) } }

fun launchOnApp(block: suspend CoroutineScope.() -> Unit) {
    appScope.launch(coroutineExceptionHandler) { block() }
}

但我总是看到这段代码崩溃。我需要使用cancelAndJoin 方法吗?请问我可以使用哪种策略来处理干净的架构和此类工作?

提前致谢

【问题讨论】:

  • 您找到解决方案了吗?
  • 我也遇到了同样的问题,请问您找到根本原因或解决方案了吗?
  • 任何消息或解决方案,我有同样的错误?
  • 解决方法是使用 GlobalScope.launch {}。这可能是旧版 kotlin-js 编译器的问题。新的 IR 编译器可能会修复它。

标签: kotlin exception coroutine kotlin-coroutines


【解决方案1】:

您可以构建一个捕获取消异常的扩展实用程序,并使用它做您想做的事情:

fun CoroutineScope.safeLaunch(block: suspend CoroutineScope.() -> Unit): Job {
  return this.launch {
    try {
      block()
    } catch (ce: CancellationException) {
      // You can ignore or log this exception
    } catch (e: Exception) {
      // Here it's better to at least log the exception
      Log.e("TAG","Coroutine error", e)
    }
  }
}

您可以将扩展与您选择的协程范围一起使用,例如全局范围:

GlobalScope.safeLaunch{
  // here goes my suspend functions and stuff
}

或任何视图模型范围:

myViewModel.viewModelScope.safeLaunch{
// here goes my suspend functions and stuff
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 2014-01-12
    • 2013-04-11
    • 2016-04-07
    • 1970-01-01
    相关资源
    最近更新 更多