비동기 처리

LEEHEES·2022년 7월 16일
0

Kotlin

목록 보기
13/13
post-thumbnail

여러 개의 루틴을 동시에 실행하는 방법

코루틴 (coroutine)

import kotlinx.coroutines.*

코루틴은 제어 범위 및 실행 범위 지정 가능
→ 코루틴의 Scope

GlobalScope

프로그램의 어디서나 제어, 동작 가능한 기본 범위

CoroutineScope

특정한 목적의 Dispatcher 를 지정하여 제어, 동작 가능한 범위

Dispatcher

Dispatchers.Default - 기본적인 백그라운드 동작
Dispatcher.IO - 네트워크나 디스크 등 I/O에 최적화된 동작
Dispatcher.Main - 메인( UI ) 스레드에서 동작
모든 플랫폼에서는 지원되지 않으니 지원되는 플랫폼에 따라 사용해야 함

val scope = CoroutineScope(Dispatcher.Default)
val coroutineA = scope.launch { }  →  반환 값이 없는 Job 객체 ( 람다함수의 형태 )
val coroutineB = scope.async { }  →  반환 값이 있는 Deffered 객체 ( 람다함수의 형태 - 마지막 구문 반환 )

코루틴은 제어되는 스코프 또는 프로그램 전체가 종료되면 함께 종료되기 때문에
코루틴이 끝까지 실행되는 것을 보장하려면 일정한 범위에서 코루틴이 모두 실행될 때까지 기다려야함

runBlocking { } 을 이용하여 프로그램이 종료되기 전 잠시 기다리며 블록을 실행 함

※ 안드로이드에서는 메인 스레드에서 runBlocking 을 걸어주면
일정 시간 응답이 없는 경우 ANR 이 발생하여 앱이 강제 종료됨

루틴의 대기를 위한 추가 함수

delay(milisecond: Long)

milisecond 단위로 루틴을 잠시 대기 시킴

Job.join()

Job 실행이 끝날때까지 대기하는 함수

Deferred.await()

Deferred 의 실행이 끝날때까지 대기하는 함수
Deferred 의 결과도 반환함

세 함수 delay() / join() / await() 는 코루틴 내부 또는 runBlocking{ } 과 같은
루틴의 대기가 가능한 구문 안에서만 동작 가능

코루틴 중단

cancel()

  1. 코루틴 내부의 delay() 함수 또는 yield() 함수가 사용된 위치까지 수행된 뒤 종료
  2. cancel() 로 인해 속성인 isActive 가 false 가 되므로 이를 확인하여 수동으로 종료

제한시간 내에 수행되면 결과물을 아니면 null 반환

withTimeoutOrNull( milisecond: Long ){
	구문
	결과 값
}

이 함수도 blocking 함수

풀코드

import kotlinx.coroutines.*

fun main() {

    blocking_function()

    println()
    println("====================")
    println()

    _cancel()

    println()
    println("====================")
    println()

    _withTimeoutOrNull()

}

fun blocking_function() {
    
    runBlocking {
        val a = launch {
            for (i in 1..5) {
                println(i)
                delay(1000)
            }
        }

        val b = async {
            "async 반환"
        }

        println("async 대기")
        println(b.await())

        println("launch 대기")
        a.join()
        println("launch 종료")
        
    }

}

fun _cancel() {
    
    runBlocking {
        val a = launch {
            for (i in 1..5) {
                println(i)
                delay(1000)
            }
        }

        val b = async {
            "async 반환"
        }

        println("async 대기")
        println(b.await())

        println("launch 취소")
        a.cancel()
        println("launch 종료")
        
    }

}

fun _withTimeoutOrNull() {

    runBlocking {
        val a = withTimeoutOrNull(50){
//        실패
//        val a = withTimeoutOrNull(500){
//        성공

            for(i in 1..10){
                println(i)
                delay(10)
            }
            "결과 값"
        }
        println(a)
    }

}

//async 대기
//1
//async 반환
//launch 대기
//2
//3
//4
//5
//launch 종료
//
//====================
//
//async 대기
//1
//async 반환
//launch 취소
//launch 종료
//
//====================
//
//1
//2
//3
//4
//null
profile
iOS 개발 공부

0개의 댓글