Sobes.tech
Middle

Bir istisna baş verdikdə korutina ilə nə baş verir?

sobes.tech Süni İntellekt

AI-dan cavab

Bir korutina daxilində istisna baş verdikdə, istisna növünə (və dispatcher/kontekst parametrlərinə) bağlı olaraq, onun necə işlənəcəyi müəyyən edilir.

  • İdarə olunmayan istisna: Əgər istisna korutina daxilində tutulmayıbsa, o, ən yaxın Job və ya CoroutineScope-a yuxarı doğru yayılır. Davranış Job növündən asılıdır:

    • Job: Standart olaraq, uşaq korutinasında istisna baş verdikdə, valideyn Job ləğv edilir və bu, onun bütün digər uşaq korutinalarının ləğv olunmasına səbəb olur. İstisna yuxarıya doğru yayılır.
    • SupervisorJob: Valideyn SupervisorJob, uşaq korutinasında istisna baş verdikdə ləğv edilmir. Yalnız istisna baş verən korutina ləğv edilir. Bu, bir uşaq tapşırığının ləğv olunmasının digərinə təsir etməməsini istəyirsinizsə, faydalıdır.
    • CoroutineScope kökü: Əgər istisna kök CoroutineScope-a (məsələn, GlobalScope və ya Job-siz yaradılmış scope) çatarsa, o, qlobal CoroutineExceptionHandler-ə ötürülür. Standart olaraq, qeydiyyatdan keçmiş bir idarəçi yoxdursa, istisna System.err-də qeyd olunur.
  • Yakala bilən istisna: Əgər istisna try-catch bloku ilə korutina daxilində tutulubsa, o, yerli şəkildə işlənir və korutina catch blokundan sonra davam edir, əgər bu mümkündürsə. İstisna yuxarıya doğru yayılmır.

  • Ləğv etmə ilə əlaqəli istisnalar (məsələn, CancellationException): Bu istisnalar xüsusi sayılır. Onlar korutinaların ləğv mexanizmi üçün istifadə olunur və ən çox idarəçi tərəfindən nəzərə alınmır. Onlar, standart olaraq, valideyn Job-un ölümcül xətasına səbəb olmur.

  • async-də istisnalar: async ilə başlatılmış korutina, istisnayı öz Deferred-inə yerləşdirir. İstisna yalnız .await() çağırıldıqda yayılır. Bu vaxta qədər, istisna "gizlənmiş" olur.

import kotlinx.coroutines.*

fun main() = runBlocking {
    val scope = CoroutineScope(SupervisorJob())

    scope.launch {
        try {
            println("Korutina 1 başladı")
            delay(100)
            throw RuntimeException("Bir şeylər səhv getdi Korutina 1-də")
        } catch (e: Exception) {
            println("Korutina 1-də tutulan istisna: ${e.message}")
        }
    }

    scope.launch {
        println("Korutina 2 başladı")
        delay(500)
        println("Korutina 2 tamamlandı")
    }

    delay(1000) // Nəticəni görmək üçün gözləyirik
    scope.cancel() // Scope-u ləğv et
}

Bu nümunədə, Korutina 1-dəki istisna tutulur və Korutina 2 davam edir, çünki SupervisorJob istifadə olunur. Əgər sadə Job istifadə olunsaydı, Korutina 1-dəki istisna Korutina 2-nin ləğv olunmasına səbəb olardı.