Kotlin'deki korutinler, işletim sisteminin iş parçacıklarını engellemeden hesaplamaları askıya alma ve yeniden başlatma desteği sunan hafif iş parçacıklarıdır. launch, async gibi işlevler aracılığıyla bir üst düzey CoroutineScope mevcut olduğunda başlatılır.
Dağıtım, korutinin hangi iş parçacığında/yürütücüde çalıştığını belirleyen CoroutineDispatcher nesneleri aracılığıyla gerçekleşir (Dispatchers.Main, Dispatchers.IO, Dispatchers.Default).
Örnek:
fun main() = runBlocking { launch(Dispatchers.IO) { val data = getDataFromNetwork() withContext(Dispatchers.Main) { updateUI(data) } } }
İptal: Korutinler, job/Scope'un iptali yoluyla iptal edilir ve bu, içsel bir CancellationException fırlatır. Korutinler, düzgün bir şekilde sonlanmak için iptal bayrağını periyodik olarak kontrol etmeli veya askıya alma işlevlerini çağırmalıdır.
Hata işleme: Korutinlerdeki istisnalar "batabilir" - örneğin, eğer bir alt korutindeki hatayı işlemezseniz, sadece kendi çalışmasını sonlandırır ve ana korutin sorunu bilmez. Bunun için SupervisorJob ve CoroutineExceptionHandler mekanizmaları vardır.
Bağlamın iletimine dair nüanslar:
Ana korutinde bir alt korutin hata ile sona ererse ve diğerleri çalışmaya devam ederse ne olur? Tüm alt korutinler iptal edilir mi?
Birçok kişi hatanın "alt katmanda kaldığını" düşünür.
Doğru cevap: Normal bir Job (veya launch) kullanılıyorsa, herhangi bir alt korutindeki hata durumunda tüm alt korutinler otomatik olarak iptal edilir. Alt korutinlerin iptal edilmemesi için SupervisorJob veya supervisorScope kullanılır:
supervisorScope { launch { error("fail") } launch { println("Bu kod çalışacak") } }
Hikaye
Yanlış hata işleme - akışın çökmesi: Projede veri yüklemek için korutinler kullanıldı. İstisnalar alt korutinler içinde "batıyordu", bu nedenle yeniden deneme/kurtarma seviyesi çalışmıyordu ve ana ekran, kullanıcıya hata mesajları olmadan boş kalıyordu.
Hikaye
Dispatchers.Main ile UI'nın donması: Genç bir Android geliştiricisi Dispatchers.Main üzerinde ağır hesaplama görevini başlattığında - UI "donmaya" başladı. Ağır hesaplamaların Dispatchers.Default veya Dispatchers.IO üzerinde çalıştırılması gerektiği konusunda bir anlayış yoktu.
Hikaye
Ebeveyn scope iptal edildiğinde AbortError: Geliştiricilerden biri, ebeveyn scope'un iptal edilmesi durumunda tüm alt korutinlerin iptal edildiğini hesaba katmadı ve çok önemli bir işlem (veri kaydetme) tamamlanmadı.