2017-11-10 1 views
4

複数のジョブインスタンスを別々のコルーチンから保存することは可能ですか?私は、コルーチンを一度に実行したいとしましょう。コルーチンは無関係で、1つのコルーチンでは実行できませんが、私はそれらを並列に実行します。 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) 
} 

このタイプのアーキテクチャはコルーチンにとって意味がありますか?

答えて

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

この方法では、一度に1つの親ジョブしかありません。私の質問は、親の仕事のリストを持つことです。私は、私が尋ねていることの例を与えた。 – 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() } 

:一度100kの雇用を創出し、この単純な例を見てくださいwhile (isActive)を。ここで

はその後キャンセルされ、2つのジョブでの例です:

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をキャンセルします。 2つの非常に異なるもの – BigApeWhat

関連する問題