Kotlin (코틀린)
Kotlin in A..Z - Coroutine(5) CoroutineScope
강태종
2020. 10. 27. 22:19
Coroutine에 접근하기 위해서는 CoroutineScope를 사용해서 접근해야 한다.
CoroutineScope는 interface형식으로 정의되어 있고, CoroutineContext를 사용해서 생성하거나, 미리 정의된 GlobalScope를 사용할 수 있다.
GlobalScope
GlobalScope는 별도의 생명주기가 없고, 실행되면 작업이 종료되거나 앱이 종료될 때까지 남아있는다.
fun main() = runBlocking {
GlobalScope.launch {
println("Running on GlobalScope ${Thread.currentThread().name}")
}
delay(1000L)
}
Running on GlobalScope DefaultDispatcher-worker-1
CoroutineScope
CoroutineScope는 Dispatchers에 미리 정의된 CoroutineContext를 사용하여 코루틴의 실행 쓰레드와 생명주기를 조절할 수 있고, 상속하여 더욱 자세하게 작동시킬 수 있다.
fun main(): Unit = runBlocking {
CoroutineScope(Dispatchers.IO).launch {
println("Running on CoroutineScope(Main) ${Thread.currentThread().name}")
}
}
Running on CoroutineScope(Main) DefaultDispatcher-worker-1
좋지않은 코루틴 구조
중간에 Exception이 발생했지만 GlobalScope는 종료되지 않고 계속 실행된다.
GlobalScope의 Job을 핸들링하기 어렵다.
fun main(): Unit = runBlocking {
try {
doSomething()
delay(2000L)
throw Exception()
} catch (e: Exception) {
println("Error")
}
// 결과를 확인하기 위한 delay
delay(10000L)
}
fun doSomething() = GlobalScope.launch {
repeat(5) {
delay(1000L)
println("Running $it")
}
}
Running 0
Error
Running 1
Running 2
Running 3
Running 4
async를 활용하였을 때 async도 CoroutineBuilder이고 새로운 Job에서 실행되기 때문에 Exception이 발생해도 계속 실행된다.
fun main(): Unit = runBlocking {
try {
async { doSomething() }
delay(2000L)
throw Exception()
} catch (e: Exception) {
println("Exception")
}
// 결과를 확인하기 위한 delay
delay(10000L)
}
suspend fun doSomething() {
repeat(5) {
delay(1000L)
println("Running $it")
}
}
Running 0
Exception
Running 1
Running 2
Running 3
Running 4
Process finished with exit code 0
권장하는 코루틴 구조
새로운 CoroutineScope에서 작업을 진행하다 예외가 발생할 경우 해당 Scope에 모든 Coroutine이 중단되면서 예외를 던진다.
fun main(): Unit = runBlocking {
try {
doSomething()
} catch (e: Exception) {
println("Exception")
}
// 결과를 확인하기 위한 delay
delay(10000L)
}
suspend fun doSomething() = coroutineScope {
async {
repeat(5) {
delay(1000L)
println("Running $it")
}
}
delay(3000L)
throw Exception()
Unit
}
Running 0
Running 1
Exception