რა ხდება კორუტინასთან, როდესაც გამონაკლისი ხდება?
sobes.tech AI
პასუხი AI-სგან
კორუტინში გამოდის გამონაკლისი, დამოკიდებულია გამონაკლისის ტიპზე (და dispatcher/კონტექსტის კონფიგურაციაზე), როგორ იქნება ის დამუშავებული.
-
არაკონტროლირებადი გამონაკლისი: თუ გამონაკლისი არ არის ჩაჭერილი კორუტინში, ის გადაეცემა ზევით კორუტინების ჰიეარარქიაში ყველაზე ახლოს მდებარე
Job-ს (ანCoroutineScope-ს). ქცევა დამოკიდებულიაJob-ის ტიპზე:Job: სტანდარტულად, თუ დეველოპერი გამონაკლისი ხდება შვილობილი კორუტინაში, მშობელიJobგაუქმდება, რაც გამოიწვევს მის სხვა შვილობილი კორუტინების გაუქმებას. გამონაკლისი გადაეცემა ზევით.SupervisorJob:SupervisorJob-ი არ გაუქმდება გამონაკლისის დროს შვილობილი კორუტინაში. მხოლოდ ის კორუტინა გაუქმდება, სადაც გამონაკლისი მოხდა. ეს სასარგებლოა, როდესაც ერთი შვილობილი დავალების გაუქმება არ უნდა ზეგავლენდეს სხვაებზე.CoroutineScope-ის ძირითადი: თუ გამონაკლისი მიაღწევსCoroutineScope-ს (მაგალითად,GlobalScopeანCoroutineScope-ით შექმნილიScope-ს გარეშე), ის გადაეცემა გლობალურ გამონაკლისების დამუშავებელსCoroutineExceptionHandler. სტანდარტულად, თუ არ არის რეგისტრირებული დამუშავებელი, გამონაკლისი იწერებაSystem.err-ში.
-
დამჭერილი გამონაკლისი: თუ გამონაკლისი არის ჩაჭერილი
try-catchბლოკით კორუტინში, ის დამუშავდება ადგილობრივად და კორუტინა გააგრძელებს შესრულებასcatch-ის შემდეგ, თუ ეს შესაძლებელია. გამონაკლისი ზევით არ გადაეცემა. -
გამონაკლისები, დაკავშირებული გაუქმებასთან (მაგალითად,
CancellationException): ეს გამონაკლისები განსაკუთრებულია. ისინი გამოიყენება კორუტინების გაუქმების მექანიზმისთვის და ჩვეულებრივ იგნორირებულია უმეტეს დამუშავებლების მიერ. ისინი არ იწვევს ფატალურ შეცდომას მშობელJob-ში. -
async-ში გამონაკლისები:async-ით დაწყებული კორუტინა აყენებს გამონაკლისს თავისDeferred-ში. გამონაკლისი გადაეცემა მხოლოდ.await()-ის დროს. მანამდე, ის "დამალულია".
import kotlinx.coroutines.*
fun main() = runBlocking {
val scope = CoroutineScope(SupervisorJob())
scope.launch {
try {
println("კორუტინა 1 დაიწყო")
delay(100)
throw RuntimeException("რაღაც მოხდა კორუტინაში 1")
} catch (e: Exception) {
println("დამჭერილი გამონაკლისი კორუტინაში 1: ${e.message}")
}
}
scope.launch {
println("კორუტინა 2 დაიწყო")
delay(500)
println("კორუტინა 2 დასრულდა")
}
delay(1000) // ველით შედეგს
scope.cancel() // ვაუქმებთ scope-ს
}
ამ მაგალითში, გამონაკლისი კორუტინაში 1 არის დამჭერილი და კორუტინა 2 აგრძელებს მუშაობას, რადგან გამოიყენება SupervisorJob। თუ გამოიყენებოდა ჩვეულებრივი Job, მაშინ გამონაკლისი კორუტინაში 1 გამოიწვევდა კორუტინას 2-ის გაუქმებას.