2017-09-07 26 views
2

kotlin의 coroutines에 대한 아이디어는 정지 및 콜백 개념을 추상화하고 간단한 순차 코드를 작성하는 것이 었습니다. 코 루틴이 일시 중단되었거나 스레드가 아닌 것처럼 걱정하지 않아도됩니다.COROTUTINE_SUSPENDED 및 Kotlin의 suspendCoroutineOrReturn

suspendCoroutineOrReturnCOROUTINE_SUSPENDED의 목적은 무엇이며 어떤 경우에 사용합니까?

답변

0

suspendCoroutineOrReturnCOROUTINE_SUSPENDED intrinsics는 매우 최근에 특정 스택 오버 플로우 문제를 해결하기 위해 1.1에서 소개되었습니다. 여기 은 예입니다

await 단순히 완성을 기다리는
fun problem() = async { 
    repeat(10_000) { 
    await(work()) 
    } 
} 

:

suspend fun <T> await(f: CompletableFuture<T>, c: Continuation<T>): Unit { 
    f.whenComplete { value, exception ->    // <- await$lambda 
    if (exception != null) c.resumeWithException(exception) else 
          c.resume(value) 
    } 
} 

것은 이제 work이 정말로 중단하지 않는 경우를 살펴 보자하지만, (예를 들어, 즉시 결과를 반환 , 캐시 됨). problem$stateMachineawait, CompletableFuture.whenComplete, await$lambda, ContinuationImpl.resume, problem$stateMachine, await, ...

본질적으로

은 아무것도 없다 : 코 루틴은 코 틀린에로 컴파일하는 것입니다 상태 머신은 다음과 통화를 할 것입니다 이제까지 일시 중단되고 상태 머신은 같은 실행 스레드 내에서 반복적으로 자신을 호출하며, 이는 StackOverflowError으로 끝납니다.

await은 coroutine이 실제로 일시 중단되었는지 여부를 구별하기 위해 특수 토큰 (COROUTINE_SUSPENDED)을 반환하여 상태 시스템이 스택 오버플로를 피할 수 있도록 허용하는 것이 좋습니다. 다음으로 코 루틴 실행을 제어하기 위해 suspendCoroutineOrReturn이 있습니다. 그 선언은 다음과 같습니다.

연속으로 제공되는 블록을 수신합니다. 기본적으로 Continuation 인스턴스 인 에 액세스하는 방법이며 일반적으로 숨겨져 있으며 컴파일하는 동안에 만 나타납니다. 블록은 임의의 값 또는 COROUTINE_SUSPENDED을 반환 할 수도 있습니다.

이 모든 것이 다소 복잡해 보입니다. Kotlin은이를 숨기려고 시도하고 위에서 언급 한 모든 것을 내부적으로 수행하는 suspendCoroutine 기능을 사용하도록 권장합니다. 여기 StackOverflowError 방지 올바른 await 구현입니다 (보조 노트 : await가 코 틀린 lib 디렉토리에 제공됩니다, 그것은 실제로 확장 기능입니다,하지만이 토론이 중요하지 않아)

suspend fun <T> await(f: CompletableFuture<T>): T = 
    suspendCoroutine { c -> 
    f.whenComplete { value, exception -> 
     if (exception != null) c.resumeWithException(exception) else 
          c.resume(value) 
    } 
} 

그러나 당신은 이제까지 먹고 싶어하는 경우 외부 연결이 이루어질 때마다 suspendCoroutineOrReturn으로 전화하고 COROUTINE_SUSPENDED을 반환해야합니다.