第三章.ライフサイクルとエラー制御


ジョブとDeferred


結果非同期関数なし:Job vs結果非同期関数:Deferred

Job

  • ロケット砲任務
  • 特定の状態に達した後、前の状態に戻ることはありません.
  • コルディンビルダーを使用して起動{}
  • 例外は、ジョブを生成する場所にジョブを伝播する.
  • //job은 예외를 던진 곳까지 전파시킨다.
    fun main(args : Array<String>) = runBlocking{
        val job = GlobalScope.launch {
            TODO("Not Implemented")
        }
    
        delay(2000L)   
    }

    ライフサイクル



    作成(New)

  • ですが、まだ実行されていないJob
  • CoroutineStart.LAZYで自動的にジョブを起動しないことができます.
  • fun main(args : Array<String>) = runBlocking{
        val job = GlobalScope.launch(start = CoroutineStart.LAZY) {
            TODO("Not Implemented")
        }
        delay(2000L)
    }

    アクティブ(Active)

  • 運転中のジョブ(一時停止中のジョブ
  • を含む)
  • join() vs start()
  • join():Job完了を待つ
  • start():Job完了を待たず
  • fun main(args : Array<String>) : Unit = runBlocking{
        val job = GlobalScope.launch(start = CoroutineStart.LAZY) {
            delay(2000L)
            println("Complete")
        }
        job.join()
    }
    join()はJobの完了を待つため、保留関数またはcoutinから呼び出す必要があります.
    fun main(args : Array<String>) {
        val task = GlobalScope.launch {
            delay(1000L)
            println("Complete")
        }
    
        task.start()
    }
    出力が完了していない状態でプログラムが閉じていることを確認できます.

    キャンセル

  • 活性とキャンセルの中間段階
  • 実行中のジョブはキャンセルが完了するまでcancel()を呼び出します.

    キャンセル


    Job
  • がキャンセルされました
  • キャンセルと完了は同一の状態であるため、Coroutine Exception Handler判定
  • を用いる.
    //handler 처리 
    fun main(args : Array<String>)  = runBlocking{
        val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
            println("Job cancelled due to ${throwable.message}")
        }
    
    
        GlobalScope.launch(exceptionHandler) {
            TODO("Not implemented yet")
        }
    
        delay(2000L)
    }
    //invokeOnCompleteion 처리
    fun main(args : Array<String>)  = runBlocking{
    
        GlobalScope.launch {
            TODO("Not implemented yet")
        }.invokeOnCompletion { cause ->
            cause?.run {
                println("Job Cancelled due to $this")
            }
        }
    
        delay(2000L)
    }

    完了

  • ジョブはxを実行しなくなり、キャンセルされたジョブ
  • を含む.

    Deferred

  • 結果を有する非同期タスクを実行するための
  • オブジェクトを返します.オブジェクトは非同期操作が完了するまで空です.
  • 未処理の異常を自動的に伝播しない.
  • join()はエラーを伝播せずに処理し、await()は伝播異常を呼び出すだけである.
  • //try-catch 문으로 예외 처리가 가능하다.
    fun main(args : Array<String>) : Unit  = runBlocking{
        val deferred = GlobalScope.async {
            TODO("Not implemented yet")
        }
    
        try {
            deferred.await()
        }catch (e : Throwable){
            println("Deferred cancelled due to ${e.message}")
        }
    }
  • Jobと同じ方法でCoroutineExceptionHandlerを処理すると、MainThreadにエラーが伝播し、エラーによってMainThreadが終了します.
    そこで、CoroutineExceptionHandlerを使用するために、エラーを受信した場所にHandlerを追加します.
  • //에러를 전파 받는 곳에 handler를 이용한다.
    fun main(args: Array<String>): Unit = runBlocking {
        val exceptionHandler = CoroutineExceptionHandler{_, handler ->
            println("Defered cancelled due to ${handler.message}")
        }
    
        val deferred = GlobalScope.async {
            TODO("Not implemented yet")
        }
    
        GlobalScope.launch(exceptionHandler){
            deferred.await()
        }.join()
    }

    状態が一方向に動く

  • ジョブがある状態に達した場合、前の状態に戻ることはありません.
  • fun main(args: Array<String>): Unit = runBlocking {
        val task = measureTimeMillis {
            val job = GlobalScope.launch{
                delay(2000L)
            }
    
            job.join()
    
            //restart
            job.start()
            job.join()
        }
    
        println("Time: $task ms")
    }
    出力2秒程度の時間を確認できます

    リファレンス

  • learning Concurrency in Kotlin
  • Coroutine 10. Deferredを使用した結果値の受信