Sobes.tech
Middle

Bir istisna oluştuğunda coroutine ile ne olur?

sobes.tech yapay zeka

AI'dan gelen yanıt

Bir coroutine içinde istisna oluştuğunda, istisna türüne (ve dispatcher/kontekst ayarlarına) bağlı olarak nasıl işleneceği belirlenir.

  • Yönetilmeyen istisna: Eğer istisna coroutine içinde yakalanmazsa, en yakın Job veya CoroutineScope'a yukarı doğru yayılır. Davranış, Job türüne bağlıdır:

    • Job: Varsayılan olarak, bir alt coroutine'de istisna oluştuğunda, üst Job iptal edilir ve bu, diğer tüm alt coroutine'lerin iptaline yol açar. İstisna yukarı doğru yayılır.
    • SupervisorJob: Üst SupervisorJob, alt coroutine'de istisna oluştuğunda iptal edilmez. Sadece istisna meydana gelen coroutine iptal edilir. Bu, bir alt görevin iptalinin diğerlerini etkilememesi istendiğinde faydalıdır.
    • CoroutineScope kök: Eğer istisna kök CoroutineScope'a (örneğin, GlobalScope veya Job olmadan oluşturulan scope) ulaşırsa, bu, küresel CoroutineExceptionHandler'a iletilir. Varsayılan olarak, kayıtlı bir işleyici yoksa, istisna System.err'de loglanır.
  • Yakalanmış istisna: Eğer istisna, coroutine içinde try-catch bloğu ile yakalanmışsa, yerel olarak işlenir ve coroutine, catch bloğundan sonra devam eder, eğer mümkünse. İstisna yukarı doğru yayılmaz.

  • İptal ile ilgili istisnalar (örneğin, CancellationException): Bu istisnalar özeldir. Coroutine iptal mekanizması için kullanılırlar ve varsayılan olarak çoğu istisna işleyicisi tarafından göz ardı edilirler. Varsayılan olarak, ana Job'un ölümcül hatasına neden olmazlar.

  • async içindeki istisnalar: async ile başlatılan coroutine, istisnayı kendi Deferred'sine yerleştirir. İstisna, yalnızca .await() çağrıldığında yayılır. Bu ana kadar, istisna "gizlenmiş" olur.

import kotlinx.coroutines.*

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

    scope.launch {
        try {
            println("Coroutine 1 başladı")
            delay(100)
            throw RuntimeException("Bir şeyler ters gitti Coroutine 1 içinde")
        } catch (e: Exception) {
            println("Coroutine 1 yakalanan istisna: ${e.message}")
        }
    }

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

    delay(1000) // Çıkışı görmek için bekle
    scope.cancel() // Scope iptal et
}

Bu örnekte, Coroutine 1 içindeki istisna yakalanır ve Coroutine 2, SupervisorJob kullanıldığı için devam eder. Eğer normal bir Job kullanılsaydı, Coroutine 1'deki istisna Coroutine 2'nin iptaline neden olurdu.