2017-11-10 9 views
4

별도의 코 루틴에서 여러 작업 인스턴스를 저장할 수 있습니까? 한 번에 두 개의 코 루틴을 실행하고 관련성이 없으며 하나의 코 루틴에서는 발생할 수 없지만 이들을 병렬로 실행하기를 원한다고 가정 해 봅시다. Android에서는 onDestroy 메소드에서 작업을 취소 할 수 있도록 작업 인스턴스를 저장해야합니다. 각 작업을 목록에 따로 저장하거나 일종의 규칙을 어기는 것이 허용 될 수 있습니까? 나는 RX에 그들이 구독을 가지고 있다는 것을 알고있다. 왜 Kotlin Coroutines에는 그와 같은 것이 없습니까?코 틀린 병렬 코 루틴

val jobList = arrayListOf<Job>() 

fun startJob1() { 
    jobList.add(launch { 
     //do some work 
    }) 

fun startJob1() { 
    jobList.add(launch { 
     //do some other unrelated work 
    }) 

override fun onDestroy() { 
    super.onDestroy() 
    cancelAllActiveJobs(jobList) 
} 

이러한 유형의 아키텍처는 coroutines에 적합한가?

답변

3

당신은 당신이 시작 Job 개체의 목록을 유지 manullay 수 있지만, 당신은 또한 사용할 수 밖으로 부모 - 자식 작업 hierarhy을 사용할 수 있습니다 시작된 작업 목록을 쉽게 관리하고 관리 할 수 ​​있습니다.

그래서, 첫째, 대신 작업 목록, 당신은 상위 작업에 대한 참조 정의

: 다음

val job = Job() 

을 때마다 새로운 코 루틴을 미사일 당신은이 작업의 아이하기 :

fun startJob1() { 
    launch(job) { // make it a child 
     //do some work 
    } 
} 

fun startJob1() { 
    launch(job) { // make it a child 
     //do some other unrelated work 
    } 
} 

마지막으로 개체를 삭제하고 모든 작업을 취소해야하는 경우 부모 작업을 취소하면됩니다.

override fun onDestroy() { 
    super.onDestroy() 
    job.cancel() 
} 

이 apporoach의 장점은 작업 목록이 자동으로 관리된다는 것입니다. 새로운 코 루틴을 시작하여 상위 작업에 추가 할 수 있으며 완료되면 자동으로 상위 작업에서 자신을 제거합니다.

당신은 가이드의 해당 섹션에서 더 읽을 수 있습니다 : 내가, 그것을 행할 수 있지만,이 올바른지 알고 https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#cancellation-via-explicit-job

+0

이 방법을 사용하면 한 번에 하나의 상위 작업 만 수행 할 수 있습니다. 제 질문은 부모 직업 목록을 갖는 것입니다. 나는 내가 묻는 것에 대한 모범을 보였다. – BigApeWhat

+0

내가 제공 한 코드는 원래 코드와 정확히 동일합니다. 창틀은 여러 작업을 실행하지만 여전히 목록에 보관됩니다. 시도 해봐.차이점은이 목록을 명시 적으로 관리 할 필요가 없다는 것입니다. 왜냐하면 모든 작업이 하위이며 부모가 자동으로 목록을 유지하기 때문입니다. –

+0

UI 스레드에서 Job() 컨텍스트를 사용할 수 있습니까? – BigApeWhat

2

그건 완전히 할 수 있고 특별한 것도 아닙니다. 그 자체는 활동 상태 이상 루프와 함께 할 수있는, 그것은 외부에서 취소되었는지 확인해야하며, 작업을 취소 할 만들기위한

val jobs = List(100_000) { // launch a lot of coroutines and list their jobs 
     launch { 
      delay(1000L) 
      print(".") 
     } 
    } 
jobs.forEach { it.join() } 

: 한 번에 10 개 만개 일자리를 창출 간단한 예를 살펴 보겠습니다 while (isActive)을 . 여기

나중에 취소됩니다 두 작업과 예입니다 :

fun main(args: Array<String>) = runBlocking { 
    val startTime = System.currentTimeMillis() 
    val jobs = arrayListOf<Job>() 
    jobs += launch { 
     var nextPrintTime = startTime 
     var i = 0 
     while (isActive) { // check if still active 
      if (System.currentTimeMillis() >= nextPrintTime) { 
       println("Job1: Sleeping ${i++} ...") 
       nextPrintTime += 500L 
      } 
     } 
    } 

    //another job 
    jobs += launch { 
     while (isActive) { // check if still active 
      if (System.currentTimeMillis() >= 42) { 
       println("Job2: Sleeping 42 ...") 
       delay(500L) 
      } 
     } 
    } 
    delay(1300L) // delay a bit 
    println("main: Cancelling the sleeping job!") 
    jobs.forEach { it.cancelAndJoin() } // cancels the job and waits for its completion 
} 
+0

는 코 루틴이 사용하는 가정하는 방법이다? 안드로이드에서 중복 작업이 무시하고 싶거나 다시 실행해야하는 오류 인 경우 각 작업의 상태를 처리하고 처리해야합니다. – BigApeWhat

+0

예. 절대적으로 그렇습니다. 작업을 취소 가능하게 만들기 위해서는, 작업 상태에 대한 루프를 사용하여 외부에서 취소되었는지를 확인해야합니다 :'while (isActive) ' – s1m0nw1

+0

주 코 루틴에서 모든 하위 작업을 저장하고에서 취소합니다 함수의 끝. 여러 개의 부모 작업을 저장하고 취소 할시기를 알고 중복 된 항목이 없는지 확인하는 것이 더 좋습니다. 부모님은 onDestroy 님을 취소 할 것입니다. 매우 다른 두 가지가 – BigApeWhat