Kotlin-Ausnahmebehandlung ---- Aufheben des Unterschieds zwischen der Ausnahme CancellationException und anderen Ausnahmen, der Reihenfolge der Ausnahmebehandlung in Coroutinen

CancellationException wird speziell von Coroutinen zum Abbrechen von Coroutinen verwendet und unterscheidet sich von anderen Ausnahmen in der Behandlung

  • Die Coroutine verwendet CancellationException intern, um den Vorgang abzubrechen, und diese Ausnahme wird ignoriert.
  • Wenn die untergeordnete Coroutine abgebrochen wird, wird die übergeordnete Coroutine nicht abgebrochen. (Wenn es sich um andere Ausnahmen handelt, wird auch die übergeordnete Coroutine beendet!)
  • Wenn eine Coroutine auf eine andere Ausnahme als CancellationException stößt, verwendet sie diese Ausnahme, um die übergeordnete Coroutine abzubrechen. Wenn sowohl die übergeordnete Coroutine als auch die untergeordnete Coroutine enden, wird die Ausnahme von der übergeordneten Coroutine behandelt.

Im folgenden Beispiel wird der Satz println("Exception capture ${exception.message}") zuletzt ausgeführt, da der dritte oben erwähnte Punkt besagt, dass die übergeordnete Coroutine Ausnahmen in allen untergeordneten Coroutinen behandelt.

step1: Wenn die zweite untergeordnete Coroutine eine Ausnahme auslöst, werfen Sie CancellationException auf die übergeordnete Coroutine, um die übergeordnete Coroutine abzubrechen.

Schritt 2: Die übergeordnete Coroutine übergibt eine Ausnahme an die erste Sub-Coroutine, und die erste Sub-Coroutine fängt die Ausnahme ab und wird schließlich ausgeführt, um Ressourcen zu bereinigen. (Das Paket withContext(NonCancellable) muss hier beim Bereinigen von Ressourcen verwendet werden, da auf diese Weise die Ressourcenbereinigungsarbeit nicht durch andere Ausnahmen gestört wird.)

Schritt 3: Wenn alle Sub-Coroutinen ausgeführt wurden, ist hier die endgültige Ausführung der ersten Sub-Coroutine, dann verwenden Sie den Handler, um die von der zweiten Sub-Coroutine ausgelöste Ausnahme zu behandeln.

@Test
fun coroutineExceptionHandlerTest2() = runBlocking<Unit> {
    var handler = CoroutineExceptionHandler{ _ , exception ->
        println("异常捕获 ${exception.message}")
    }
    var job1 = GlobalScope.launch(handler) {
        launch {
            try {
                println("第一个子协程进入")
                delay(Long.MAX_VALUE)
            } catch (e : java.lang.Exception) {
                println("第一个子协程捕获到异常,${e.message}")
            } finally {
                withContext(NonCancellable) {
                    println("第一个子协程准备清理资源")
                    delay(5000)
                    println("第一个子协程准备清理资源完毕")
                }
            }
        }
        launch {
            println("第二个子协程进入")
            delay(1000)
            throw ArithmeticException("抛出一个算数异常!!!!!!!!!")
        }
    }
    job1.join()
}
第一个子协程进入
第二个子协程进入
第一个子协程捕获到异常,Parent job is Cancelling
第一个子协程准备清理资源
第一个子协程准备清理资源完毕
异常捕获 抛出一个算数异常!!!!!!!!!

 

Ich denke du magst

Origin blog.csdn.net/mldxs/article/details/127178858
Empfohlen
Rangfolge