@@ -52,6 +52,7 @@ This is a short guide on core features of `kotlinx.coroutines` with a series of
5252 * [ Children of a coroutine] ( #children-of-a-coroutine )
5353 * [ Combining contexts] ( #combining-contexts )
5454 * [ Naming coroutines for debugging] ( #naming-coroutines-for-debugging )
55+ * [ Cancellation via explicit job] ( #cancellation-via-explicit-job )
5556* [ Channels] ( #channels )
5657 * [ Channel basics] ( #channel-basics )
5758 * [ Closing and iteration over channels] ( #closing-and-iteration-over-channels )
@@ -953,6 +954,55 @@ The output it produces with `-Dkotlinx.coroutines.debug` JVM option is similar t
953954[main @main#1] The answer for v1 / v2 = 42
954955```
955956
957+ ### Cancellation via explicit job
958+
959+ Let us put our knowledge about contexts, children and jobs together. Assume that our application has
960+ an object with a lifecycle, but that object is not a coroutine. For example, we are writing an Android application
961+ and launch various coroutines in the context of an Android activity to perform asynchronous operations to fetch
962+ and update data, do animations, etc. All of these coroutines must be cancelled when activity is destroyed
963+ to avoid memory leaks.
964+
965+ We can manage a lifecycle of our coroutines by creating an instance of [ Job] that is tied to
966+ the lifecycle of our activity. A job instance is created using [ Job()] [ Job.invoke ] factory function
967+ as the following example shows. We need to make sure that all the coroutines are started
968+ with this job in their context and then a single invocation of [ Job.cancel] terminates them all.
969+
970+ ``` kotlin
971+ fun main (args : Array <String >) = runBlocking<Unit > {
972+ val job = Job () // create a job object to manage our lifecycle
973+ // now launch ten coroutines for a demo, each working for a different time
974+ val coroutines = List (10 ) { i ->
975+ // they are all children of our job object
976+ launch(context + job) { // we use the context of main runBlocking thread, but with our own job object
977+ delay(i * 200L ) // variable delay 0ms, 200ms, 400ms, ... etc
978+ println (" Coroutine $i is done" )
979+ }
980+ }
981+ println (" Launched ${coroutines.size} coroutines" )
982+ delay(500L ) // delay for half a second
983+ println (" Cancelling job!" )
984+ job.cancel() // cancel our job.. !!!
985+ delay(1000L ) // delay for more to see if our coroutines are still working
986+ }
987+ ```
988+
989+ > You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-context-09.kt )
990+
991+ The output of this example is:
992+
993+ ```
994+ Launched 10 coroutines
995+ Coroutine 0 is done
996+ Coroutine 1 is done
997+ Coroutine 2 is done
998+ Cancelling job!
999+ ```
1000+
1001+ As you can see, only the first three coroutines had printed a message and the others were cancelled
1002+ by a single invocation of ` job.cancel() ` . So all we need to do in our hypothetical Android
1003+ application is to create a parent job object when activity is created, use it for child coroutines,
1004+ and cancel it when activity is destroyed.
1005+
9561006## Channels
9571007
9581008Deferred values provide a convenient way to transfer a single value between coroutines.
@@ -1299,7 +1349,9 @@ The first four elements are added to the buffer and the sender suspends when try
12991349[ Deferred ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html
13001350[ Deferred.await ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/await.html
13011351[ Job ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-job/index.html
1352+ [ Job.cancel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-job/cancel.html
13021353[ Job.start ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-job/start.html
1354+ [ Job.invoke ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-job/invoke.html
13031355[ NonCancellable ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-non-cancellable/index.html
13041356[ Unconfined ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-unconfined/index.html
13051357[ CancellationException ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-cancellation-exception.html
0 commit comments