Sobes.tech
Middle

Welche Fehlerbehandlungsverfahren in Koroutinen kennen Sie?

sobes.tech KI

Antwort von AI

  • Verwendung von try...catch-Blöcken. Standardmethode zur Fehlerbehandlung. Funktioniert innerhalb einer Coroutine.

    // Anwendung von try-catch
    suspend fun fetchData(): String {
        return try {
            // Operation, die eine Ausnahme auslösen kann
            throw Exception("Fehler beim Laden der Daten")
            "Daten erfolgreich geladen"
        } catch (e: Exception) {
            "Fehler: ${e.message}"
        }
    }
    

    try...catch ist nicht geeignet, um unbehandelte Ausnahmen zu behandeln, die von Kind-Coroutines geworfen werden, die in einem anderen CoroutineScope laufen.

  • CoroutineExceptionHandler. Fängt unbehandelte Ausnahmen ab, die von Coroutines geworfen werden, die in diesem CoroutineScope oder seinen Kind-Scopes gestartet wurden.

    // CoroutineExceptionHandler
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Abgefangene Ausnahme: $exception")
    }
    
    // Anwendung des CoroutineExceptionHandler
    GlobalScope.launch(handler) {
        // Coroutine, die eine Ausnahme werfen kann
        throw Exception("Fehler in der Coroutine")
    }
    

    CoroutineExceptionHandler greift nur bei unbehandelten Ausnahmen, die nicht durch den Mechanismus der strukturierten Nebenläufigkeit abgefangen werden.

  • SupervisorJob und supervisorScope. Im Gegensatz zu einem normalen Job führt eine Fehlerhafte Kind-Coroutine dazu, dass der Eltern-Job abgebrochen wird. SupervisorJob bricht den Eltern-Job bei Fehlern in Kind-Coroutines nicht ab. supervisorScope erstellt einen CoroutineScope mit einem SupervisorJob.

    // Verwendung von supervisorScope
    suspend fun loadMultipleData() = supervisorScope {
        val data1 = async {
            // Kann eine Ausnahme auslösen
            throw Exception("Fehler bei Daten 1")
            "Daten 1"
        }
        val data2 = async {
            "Daten 2"
        }
    
        // Fehlerbehandlung für eine bestimmte async
        try {
            println("Ergebnis 1: ${data1.await()}")
        } catch (e: Exception) {
            println("Fehler beim Laden der Daten 1: ${e.message}")
        }
        println("Ergebnis 2: ${data2.await()}")
    }
    

    Wird für unabhängige Kind-Aufgaben verwendet, bei denen ein Fehler einer Aufgabe die anderen nicht beeinflussen soll. Ersetzt nicht try...catch oder CoroutineExceptionHandler, sondern ändert das Verhalten bei der Fehlerweiterleitung.

  • Fehlerweiterleitung in der strukturierten Nebenläufigkeit. Standardmäßig beendet eine Ausnahme in einer Kind-Coroutine die Eltern-Coroutine und alle Geschwister.

    // Beispiel für Fehlerweiterleitung
    runBlocking {
        val job = launch {
            launch { // Kind-Coroutine 1
                delay(100)
                throw Exception("Fehler in Kind 1")
            }
            launch { // Kind-Coroutine 2
                delay(200)
                println("Kind 2 beendet")
            }
        }
        try {
            job.join()
        } catch (e: Exception) {
            println("Fehler in Elternteil abgefangen: $e")
        }
    }
    

    Dies ist das Standardverhalten der strukturierten Nebenläufigkeit, um Ressourcen- und Zustandslecks zu vermeiden.

  • Verwendung von async mit await(). Ausgelöste Ausnahmen in async werden nicht automatisch propagiert. Sie werden in Deferred gespeichert und nur bei await() ausgelöst.

    // Fehlerbehandlung mit async/await
    suspend fun safeAsyncCall() = coroutineScope {
        val deferred = async {
            throw Exception("Fehler in async")
            "Async-Ergebnis"
        }
    
        try {
            val result = deferred.await()
            println("Ergebnis: $result")
        } catch (e: Exception) {
            println("Abgefangene Ausnahme aus async: ${e.message}")
        }
    }
    

    Dies ermöglicht eine selektive Fehlerbehandlung für jede asynchrone Aufgabe.

Methode Zweck Uncaught? Änderung der Weiterleitung?
try...catch Fehlerbehandlung innerhalb der aktuellen Coroutine Nein Nein
CoroutineExceptionHandler Abfangen unbehandelter Ausnahmen im Scope Ja Nein
SupervisorJob/Scope Änderung des Verhaltens bei Fehlerweiterleitung Nein Ja
Strukturiertes Nebenläufigkeit Automatisches Canceln bei Fehler Ja Ja
async + await() Verzögerte Fehlerweiterleitung Nein Ja (vor await)