gpt4 book ai didi

kotlin - 避免在子协程异常时取消父作业

转载 作者:行者123 更新时间:2023-12-01 11:15:03 33 4
gpt4 key购买 nike

我正在试验 在 Android 上处理 Kotlin 协程中的异常 .

我的用例是我想在后台(以异步方式)执行一堆任务并在单个事件上更新多个 UI 组件。

我设计了一个 BaseActivity实现结构 CoroutineScope所以我可以结合使用事件生命周期调用的协程。

另外,我有一个 Repository处理网络调用的类。

我已经实现了同时运行多个任务。我知道我是否使用单个 Job反对取消 onDestroy() 上的所有协程事件和在事件中执行( launch )多个协程,任何单个协程中的异常将取消 Job来自其 CoroutineContext .从 Job附加到事件的生命周期,它也会取消所有其他协程。

我试过使用 CoroutineExceptionHandler .它捕获异常但取消了 Job也。结果取消了所有其他协程。

我想要的是?

  • 可以使用单例 Job要附加事件生命周期的对象
  • 一个协程中的异常 不应该取消其他协程

  • 在下面添加代码
    class BaseActivity : AppCompatActivity(), CoroutineScope {

    val job = Job()
    override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    launch(coroutineContext) {
    Log.i("GURU", "launch1 -> start")
    val result1Deferred = async { Repository().getData(1) }
    val result2Deferred = async { Repository().getData(2) }

    Log.i("GURU", "awaited result1 = " + result1Deferred.await() + result2Deferred.await())
    }

    //If Exception is Thrown, Launch1 should still continue to complete
    advancedLaunch(coroutineContext) {
    Log.i("GURU", "launch2 -> start")
    val result1Deferred = async { Repository().getData(3) }

    val result2Deferred = async { Repository().getData(4) }

    delay(200)
    throw Exception("Exception from launch 2")


    Log.i("GURU", "awaited result2 = " + result1Deferred.await() + result2Deferred.await())
    }


    }



    fun CoroutineScope.advancedLaunch(context: CoroutineContext = EmptyCoroutineContext,
    exceptionBlock: (Throwable) -> Unit = {Log.i("GURU", it.message)},
    launchBlock: suspend CoroutineScope.() -> Unit) {
    val exceptionHandler = CoroutineExceptionHandler { _, throwable -> exceptionBlock(throwable)}
    launch(context + exceptionHandler) { launchBlock() }
    }

    override fun onDestroy() {
    super.onDestroy()
    job.cancel()
    Log.i("GURU", "job -> cancelled")
    }
    }

    这个的日志结果是
    I/GURU: launch1 -> start
    I/GURU: launch2 -> start
    I/GURU: getData -> start 1
    I/GURU: getData -> start 2
    I/GURU: getData -> start 4
    I/GURU: getData -> start 3
    I/GURU: Exception from launch 2

    --------- beginning of crash

    最佳答案

    您可能想更换您的 Job SupervisorJob .

    它可以防止异常“向上”传播(一个失败的子项不会导致整个作业失败),但仍然允许您“向下”(向正在运行的子项)推送取消。

    关于kotlin - 避免在子协程异常时取消父作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53132989/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com