Milyen hibakezelési módszereket ismersz a korutinokban?
sobes.tech MI
Válasz az MI-től
-
A
try...catchblokkok használata. Az exception kezelés standard módja. Belül működik a coroutine-on.// try-catch alkalmazása suspend fun fetchData(): String { return try { // Opeáció, ami kivételt dobhat throw Exception("Adatok betöltése közben hiba") "Adatok sikeresen betöltve" } catch (e: Exception) { "Hiba: ${e.message}" } }A
try...catchnem alkalmas a gyermek coroutine-kból származó, nem kezelt kivételek kezelésére, amelyek másCoroutineScope-ban futnak. -
CoroutineExceptionHandler. Elkapja a nem kezelt kivételeket, amelyeket a coroutine-ok dobnak, ha azok ebben aCoroutineScope-ban vagy annak gyermek scope-jaiban futnak.// CoroutineExceptionHandler val handler = CoroutineExceptionHandler { _, exception -> println("Elkapott kivétel: $exception") } // CoroutineExceptionHandler alkalmazása GlobalScope.launch(handler) { // Coroutine, ami kivételt dobhat throw Exception("Hiba a coroutine-ban") }A
CoroutineExceptionHandlercsak azokhoz az esetekhez aktiválódik, amikor a kivételeket nem kezeli a strukturált konkurencia mechanizmusa. -
SupervisorJobéssupervisorScope. Ellentétben a szokásosJob-bal, ha egy gyermek coroutine hibával jár, az nem okozza a szülőJob-jának törlését. AsupervisorScopeegyCoroutineScope-t hoz létreSupervisorJob-bal.// supervisorScope használata suspend fun loadMultipleData() = supervisorScope { val data1 = async { // Hibát dobhat throw Exception("Hiba az adatok 1-ben") "Adatok 1" } val data2 = async { "Adatok 2" } // Hibakezelés egy adott async esetén try { println("Eredmény 1: ${data1.await()}") } catch (e: Exception) { println("Hiba az adatok 1 betöltésekor: ${e.message}") } println("Eredmény 2: ${data2.await()}") }Ez független gyermek feladatokra használható, ahol egy hiba nem befolyásolja a többit. Nem helyettesíti a
try...catch-t vagy aCoroutineExceptionHandler-t, hanem megváltoztatja a kivételek terjedésének viselkedését. -
A kivételek terjedése a strukturált konkurenciában. Alapértelmezés szerint, ha egy gyermek coroutine kivételt dob, az az anya coroutine-t és annak összes testvérét is törli.
// Kivétel terjedésének példája runBlocking { val job = launch { launch { // Gyermek coroutine 1 delay(100) throw Exception("Hiba a gyermek 1-ben") } launch { // Gyermek coroutine 2 delay(200) println("Gyermek 2 befejeződött") } } try { job.join() } catch (e: Exception) { println("Kezelő kivétel az anya coroutine-ban: $e") } }Ez a strukturált konkurencia alap viselkedése, amely segít elkerülni az erőforrás szivárgásokat és állapotokat.
-
Az
asyncésawait()használata. Azasync-ban dobott kivételek nem terjednek automatikusan. Ezek aDeferred-ben tárolódnak, és csak azawait()hívásakor dobódnak ki.// Kivételkezelés async/await segítségével suspend fun safeAsyncCall() = coroutineScope { val deferred = async { throw Exception("Hiba az async-ben") "Async eredmény" } try { val result = deferred.await() println("Eredmény: $result") } catch (e: Exception) { println("Kivétel elkapva az async-ből: ${e.message}") } }Ez lehetővé teszi az egyes aszinkron feladatok hibáinak szelektív kezelését.
| Módszer | Cél | Uncaught-ot kezel? | Terjedést módosít? |
|---|---|---|---|
try...catch |
Kivételkezelés a jelenlegi coroutine-on belül | Nem | Nem |
CoroutineExceptionHandler |
Nem kezelt kivételek elfogása Scope-ben | Igen | Nem |
SupervisorJob/Scope |
A kivételek terjedésének viselkedésének módosítása | Nem | Igen |
| Strukturált konkurencia | Automatikus törlés hiba esetén | Igen | Igen |
async + await() |
Késleltetett kivétel terjesztés | Nem | Igen (az await-ig) |