본문 바로가기
Android

[Coroutine] 취소와 타임아웃(2) - finally, withContext, withTimeout

by Diane_KIM 2024. 5. 6.

 finally 

예외 처리 구문인 try-catch 블록의 일부로 사용되는 키워드
try 블록을 실행한 후에 항상 실행되는 블록을 정의할 때 사용
  • launch에서 자원을 할당한 경우에 해제를 하려고 할때 사용
  • 예를들어, 파일이나 소켓같은 경우 항상 열고 닫아야하는데, 코루틴이 취소될때도 자원들은 정상적으로 해제가 되어야 한다.
  • suspend 함수가 취소가 되었을때 내부적으로 JobCancellationException이 발생되는데, 이때 finally 로 넘어가 처리된다. 
  • 해당 Exception이 발생했을때, try 안에 있는 함수는 실행되지 않고, 바로 finally 안에 있는 함수가 실행된다

 

 withContext(NonCancellable)

withContext는 코루틴의 Context를 임시로 변경하는 함수로, 주어진 Context로 변경하고, 제공된 블록을 실행한 다음 원래의 Context로 복귀해준다.NonCancellable은 코루틴이 취소되지 않는 특별한 Context로, 이 Context에서 실행되는 코드 블록은 취소 요청을 무시한다 

  • cancel이 이루어져서 finally가 수행이 되는데, 이 수행 중에도 캔슬이 일어날 수 있음
  • 이때 무조건 수행이 되어야 된다면 withContext로 취소 불가능한 블록을 만들어 사용할 수 있다
val job = launch {
    try {
        println("Coroutine is running")
        delay(1000)  // 취소 가능 포인트
        println("Still running after delay")
    } finally {
        withContext(NonCancellable) {
            println("Running cleanup code")
            delay(1000)  // 이 delay는 취소 불가
            println("Cleanup completed")
        }
    }
}



withTimeout 

일정 시간 후에 종료하고 싶을때 사용하는 함수
  • 코드 블록이 실행되는 시간이 정해진 시간보다 초과될 경우 TimeoutCancellationException이 발생
  • 예외처리를 해주려면 try - catch를 사용하거나 withTimeOrNull을 사용하면 된다
fun main() = runBlocking {
	val result = withTimeoutOrNull(200L) {
        doOne()
        true
    } ?: false
    println(result)
}

 

withTimeoutOrNull는 타임 아웃이 발생할 때 null을 발생하게 하는 함수다.

  • 엘비스 연산자(?:)로 withTimeoutOrNull 리턴값이 null일경우 false를 설정하게 되어있다.
  • 0.2초 안에 doOne() 함수가 모두 실행이 되지 않으면 result 라는 변수는 false값을 반환할 것이고, 시간초과하지 않으면 true를 리턴하고 해당 결과를 출력할 것이다