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...catchist nicht geeignet, um unbehandelte Ausnahmen zu behandeln, die von Kind-Coroutines geworfen werden, die in einem anderenCoroutineScopelaufen. -
CoroutineExceptionHandler. Fängt unbehandelte Ausnahmen ab, die von Coroutines geworfen werden, die in diesemCoroutineScopeoder 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") }CoroutineExceptionHandlergreift nur bei unbehandelten Ausnahmen, die nicht durch den Mechanismus der strukturierten Nebenläufigkeit abgefangen werden. -
SupervisorJobundsupervisorScope. Im Gegensatz zu einem normalenJobführt eine Fehlerhafte Kind-Coroutine dazu, dass der Eltern-Job abgebrochen wird.SupervisorJobbricht den Eltern-Job bei Fehlern in Kind-Coroutines nicht ab.supervisorScopeerstellt einenCoroutineScopemit einemSupervisorJob.// 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...catchoderCoroutineExceptionHandler, 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
asyncmitawait(). Ausgelöste Ausnahmen inasyncwerden nicht automatisch propagiert. Sie werden inDeferredgespeichert und nur beiawait()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) |