Welke manieren van foutafhandeling in coroutines ken je?
sobes.tech AI
Antwoord van AI
-
Gebruik van
try...catchblokken. Standaardmethode voor foutafhandeling. Werkt binnen een coroutine.// Toepassing van try-catch suspend fun fetchData(): String { return try { // Operatie die een uitzondering kan veroorzaken throw Exception("Fout bij het laden van gegevens") "Gegevens succesvol geladen" } catch (e: Exception) { "Fout: ${e.message}" } }try...catchis niet geschikt voor het afhandelen van uncaught uitzonderingen die worden gegooid uit child coroutines die in een andereCoroutineScopeworden uitgevoerd. -
CoroutineExceptionHandler. Vangt onverwerkte uitzonderingen op die door coroutines worden gegooid, die in dezeCoroutineScopeof in zijn childCoroutineScopeworden gestart.// CoroutineExceptionHandler val handler = CoroutineExceptionHandler { _, exception -> println("Vangst exception: $exception") } // Toepassing van CoroutineExceptionHandler GlobalScope.launch(handler) { // Coroutine die een uitzondering kan gooien throw Exception("Fout in coroutine") }CoroutineExceptionHandlerwordt alleen geactiveerd voor uitzonderingen die niet worden afgehandeld door het gestructureerde concurrency mechanisme. -
SupervisorJobensupervisorScope. In tegenstelling tot een gewoonJob, wanneer een child coroutine een fout veroorzaakt, leidt dit niet tot het annuleren van de parentJob.supervisorScopecreëert eenCoroutineScopemet eenSupervisorJob.// Gebruik van supervisorScope suspend fun loadMultipleData() = supervisorScope { val data1 = async { // Kan een uitzondering veroorzaken throw Exception("Fout in data 1") "Data 1" } val data2 = async { "Data 2" } // Foutafhandeling voor een specifieke async try { println("Resultaat 1: ${data1.await()}") } catch (e: Exception) { println("Fout bij laden data 1: ${e.message}") } println("Resultaat 2: ${data2.await()}") }Wordt gebruikt voor onafhankelijke child taken, waarbij de fout van de ene niet de andere mag beïnvloeden. Vervangt niet
try...catchofCoroutineExceptionHandler, maar verandert het gedrag van het verspreiden van uitzonderingen. -
Verspreiding van uitzonderingen in gestructureerde concurrency. Standaard, een uitzondering in een child coroutine annuleert de parent coroutine en al haar siblings.
// Voorbeeld van verspreiding van een uitzondering runBlocking { val job = launch { launch { // Child coroutine 1 delay(100) throw Exception("Fout in child 1") } launch { // Child coroutine 2 delay(200) println("Child 2 voltooid") } } try { job.join() } catch (e: Exception) { println("Exception opgevangen in parent: $e") } }Dit is het basisgedrag van gestructureerde concurrency, dat helpt resource leaks en toestand te voorkomen.
-
Gebruik van
asyncmetawait(). Uitzonderingen die inasyncworden gegooid, worden niet automatisch verspreid. Ze worden opgeslagen binnenDeferreden worden alleen gegooid bij het aanroepen vanawait().// Afhandeling van uitzonderingen met async/await suspend fun safeAsyncCall() = coroutineScope { val deferred = async { throw Exception("Fout in async") "Async resultaat" } try { val result = deferred.await() println("Resultaat: $result") } catch (e: Exception) { println("Vangst exception uit async: ${e.message}") } }Dit maakt het mogelijk om fouten selectief te verwerken voor elke asynchrone taak.
| Methode | Doel | Vangt uncaught? | Verandert verspreiding? |
|---|---|---|---|
try...catch |
Afhandeling van uitzonderingen binnen huidige coroutine | Nee | Nee |
CoroutineExceptionHandler |
Vangt onverwerkte uitzonderingen in Scope | Ja | Nee |
SupervisorJob/Scope |
Verandert gedrag van verspreiding van uitzonderingen | Nee | Ja |
| Gestructureerde concurrency | Automatische annulering bij fout | Ja | Ja |
async + await() |
Uitgestelde verspreiding van uitzonderingen | Nee | Ja (voor await) |