Notice
Recent Posts
Recent Comments
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

훌륭한 개발자가 되기 위하여

일시 중단 함수와 코루틴 본문

안드로이드

일시 중단 함수와 코루틴

jay20033 2025. 1. 13. 18:18

일시 중단 함수

일시 중단 함수와 코루틴

  • 일시 중단 함수란 suspend fun 키워드로 선언되는 함수로 함수 내에 일시 중단 지점 을 포함할 수 있는 함수이다.
  • 일시 중단 함수는 코루틴의 일시 중단 지점이 포함된 코드를 재사용할 수 있는 코드의 집합으로 만드는데 사용된다.
  • 일시 중단 지점이 포함될 수 있기 때문에 코루틴에서만 호출 가능하다.

일시 중단 함수의 오해

  • 일시 중단 함수는 코루틴이 아니다. 👉 단순히 일시 중단 지점을 포함할 수 있는 함수일 뿐이다.
  • 일시 중단 함수를 별도의 코루틴에서 실행하려면 일시 중단 함수 호출부를 코루틴 빌더 함수로 감싸야 한다.
fun main() = runBlocking<Unit> {
    val startTime = System.currentTimeMillis()
    val job1 = launch {
        delayAndPrintHelloWorld()
    }
    val job2 = launch {
        delayAndPrintHelloWorld()
    }
    joinAll(job1, job2)
    println(getElapsedTime(startTime))
}

suspend fun delayAndPrintHelloworld() {
    delay(1000L)
    println("Hello World")
}

일시 중단 함수의 사용

일시 중단 함수의 호출 가능 지점

  • 일시 중단 함수는 일시 중단을 할 수 있는 곳에서만 호출할 수 있다.
  1. 코루틴 내부
    • 일시 중단 가능한 작업 단위인 코루틴은 일시 중단 함수를 호출할 수 있다.
  2. 일시 중단 함수
    • 일시 중단 함수는 다른 일시 중단 함수를 호출할 수 있다.
    • 일시 중단 함수는 CoroutineScope에 접근할 수 없기 때문에 별도 처리 없이 코루틴 빌더 함수를 호출할 수 없다.
    • coroutineScope 함수를 사용하면 일시 중단 함수 내부에 새로운 CoroutineScope 객체를 생성할 수 있다.
    • coroutineScope 함수는 구조화를 깨지 않는 CoroutineScope 객체를 생성한다.
    suspend fun searchByKeyword(keyword: String): Array<String> = coroutineScope {
        val dbResultsDeferred = async {
            searchFromDB(keyword)
        }
        val serverResultsDeferred = async {
            searchFromServer(keyword)
        }
        // async 함수 사용시 노출된 예외처리도 해줘야 함
        val dbResults = try {
            dbResultsDeferred.await()
        } catch (e: Exception) {
            arrayOf()
        }
        val serverResults = try {
            serverResultsDeferred.await()
        } catch (e: Exception) {
            arrayOf()
        }
    
        return@coroutineScope arrayOf(*dbResults, *serverResults)
    }
    
    suspend fun searchFromDB(keyword: String): Array<String> {
        delay(1000L)
        return arrayOf("[DB]${keyword}1", "[DB]${keyword}2")
    }
    
    suspend fun searchFromServer(keyword: String): Array<String> {
        delay(1000L)
        return arrayOf("[Server]${keyword}1", "[Server]${keyword}2")
    }

위와 같이 구현하면 오류발생시 치명적인 결과를 가져올 수 있다.

이런 문제를 해결하기 위해서는 coroutineScope 대신 supervisorScope 를 사용하여 자식 코루틴에서 발생한 예외를 전파받지 않도록 조치한다.