Sobes.tech
Middle

Milliseid vigade töötlemise viise te korutinates tead?

sobes.tech AI

Vastus AI-lt

  • Kasutades try...catch plokke. Tavaline erandite töötlemise viis. Töötab korutinas sees.

    // Kasutades try-catch
    suspend fun fetchData(): String {
        return try {
            // Operatsioon, mis võib visata erandi
            throw Exception("Andmete laadimise viga")
            "Andmed edukalt laaditud"
        } catch (e: Exception) {
            "Viga: ${e.message}"
        }
    }
    

    try...catch ei sobi käsitleda mittehakkamata erandeid, mida viskab lapsekorutina, mis on käivitatud teises CoroutineScope.

  • CoroutineExceptionHandler. Püüab kinni töötlemata erandid, mida viskab korutina, mis on käivitatud selles CoroutineScope või selle alam-CoroutineScope-des.

    // CoroutineExceptionHandler
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Püüritud erand: $exception")
    }
    
    // Kasutades CoroutineExceptionHandler
    GlobalScope.launch(handler) {
        // Korutina, mis võib visata erandi
        throw Exception("Viga korutinas")
    }
    

    CoroutineExceptionHandler töötab ainult töötlemata erandite puhul, mis ei ole struktureeritud konkurentsi mehhanismi kaudu töödeldud.

  • SupervisorJob ja supervisorScope. Erinevalt tavalisest Job-ist, kui lapsekorutina viga põhjustab vanem-Job-i tühistamise, siis SupervisorJob seda ei tee. supervisorScope loob CoroutineScope koos SupervisorJob-iga.

    // Kasutades supervisorScope
    suspend fun loadMultipleData() = supervisorScope {
        val data1 = async {
            // Võib visata erandi
            throw Exception("Viga andmetes 1")
            "Andmed 1"
        }
        val data2 = async {
            "Andmed 2"
        }
    
        // Võib töödelda erandi konkreetses `async`
        try {
            println("Tulemus 1: ${data1.await()}")
        } catch (e: Exception) {
            println("Viga andmete laadimisel 1: ${e.message}")
        }
        println("Tulemus 2: ${data2.await()}")
    }
    

    Kasutatakse sõltumatute alamülesannete jaoks, kus ühe viga ei tohiks mõjutada teisi. Ei asenda try...catch ega CoroutineExceptionHandler, vaid muudab erandite leviku käitumist.

  • Erandite levik struktuuriseeritud konkurentsis. Vaikimisi tühistab lapsekorutina erandi vanemkorutina ja kõik selle õed.

    // Näide erandi levikust
    runBlocking {
        val job = launch {
            launch { // Lapsekorutina 1
                delay(100)
                throw Exception("Viga lapse 1")
            }
            launch { // Lapsekorutina 2
                delay(200)
                println("Lapse 2 täidetud")
            }
        }
        try {
            job.join()
        } catch (e: Exception) {
            println("Erand püüdsid vanem: $e")
        }
    }
    

    See on põhikäitumine struktureeritud konkurentsis, mis aitab vältida ressursside ja olekute lekkimist.

  • Kasutades async koos await(). Erandid, mis visatakse async, ei levi automaatselt. Need salvestatakse Deferred-i ja visatakse välja ainult await() kutsumisel.

    // Erandite töötlemine async/await-iga
    suspend fun safeAsyncCall() = coroutineScope {
        val deferred = async {
            throw Exception("Viga async")
            "Async tulemus"
        }
    
        try {
            val result = deferred.await()
            println("Tulemus: $result")
        } catch (e: Exception) {
            println("Püüritud erand async-ist: ${e.message}")
        }
    }
    

    See võimaldab valikuliselt töödelda iga asünkroonse ülesande vigu.

Meetod Otstarve Kas töötleb neapstrādatud? Kas muudab levikut?
try...catch Erandite töötlemine praeguses korutinas Ei Ei
CoroutineExceptionHandler Töötlemata erandite püüdmine Scope'is Jah Ei
SupervisorJob/Scope Erandite leviku käitumise muutmine Ei Jah
Struktureeritud konkurents Automaatne tühistamine vea korral Jah Jah
async + await() Viivitusega levitamine erandite Ei Jah (enne await)