@@ -87,7 +87,13 @@ public interface CoroutineScope {
87
87
* Adds the specified coroutine context to this scope, overriding existing elements in the current
88
88
* scope's context with the corresponding keys.
89
89
*
90
- * This is a shorthand for `CoroutineScope(thisScope.coroutineContext + context)`.
90
+ * This is a shorthand for `CoroutineScope(thisScope.coroutineContext + context)` and can be used as
91
+ * a combinator with existing constructors:
92
+ * ```
93
+ * class MyActivity {
94
+ * val uiScope = MainScope() + CoroutineName("MyActivity")
95
+ * }
96
+ * ```
91
97
*/
92
98
public operator fun CoroutineScope.plus (context : CoroutineContext ): CoroutineScope =
93
99
ContextScope (coroutineContext + context)
@@ -117,13 +123,30 @@ public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatch
117
123
/* *
118
124
* Returns `true` when the current [Job] is still active (has not completed and was not cancelled yet).
119
125
*
120
- * Check this property in long-running computation loops to support cancellation:
126
+ * Coroutine cancallation [is cooperative](https://kotlinlang.org/docs/cancellation-and-timeouts.html#cancellation-is-cooperative)
127
+ * and normally, it's checked if a coroutine is cancelled when it *suspends*, for example,
128
+ * when trying to read from a [channel][kotlinx.coroutines.channels.Channel] that is empty.
129
+ *
130
+ * Sometimes, a coroutine does not need to perform suspending operations, but still wants to be cooperative
131
+ * and respect cancellation.
132
+ *
133
+ * The [isActive] property is inteded to be used for scenarios like this:
121
134
* ```
122
- * while (isActive) {
123
- * // do some computation
135
+ * val watchdogDispatcher = Dispatchers.IO.limitParallelism(1)
136
+ * fun backgroundWork() {
137
+ * println("Doing bookkeeping in the background in a non-suspending manner")
138
+ * Thread.sleep(100L) // Sleep 100ms
139
+ * }
140
+ * // Part of some non-trivial CoroutineScope-confined lifecycle
141
+ * launch(watchdogDispatcher) {
142
+ * while (isActive) {
143
+ * // Repetitively do some background work that is non-suspending
144
+ * backgroundWork()
145
+ * }
124
146
* }
125
147
* ```
126
148
*
149
+ * This function returns `true` if there is no [job][Job] in the scope's [coroutineContext][CoroutineScope.coroutineContext].
127
150
* This property is a shortcut for `coroutineContext.isActive` in the scope when
128
151
* [CoroutineScope] is available.
129
152
* See [coroutineContext][kotlin.coroutines.coroutineContext],
@@ -292,24 +315,40 @@ public fun CoroutineScope.cancel(cause: CancellationException? = null) {
292
315
public fun CoroutineScope.cancel (message : String , cause : Throwable ? = null): Unit = cancel(CancellationException (message, cause))
293
316
294
317
/* *
295
- * Ensures that current scope is [active][CoroutineScope.isActive].
318
+ * Throws the [CancellationException] that was the scope's cancellation cause if the scope is no longer [active][CoroutineScope.isActive].
296
319
*
297
- * If the job is no longer active, throws [CancellationException].
298
- * If the job was cancelled, thrown exception contains the original cancellation cause.
299
- * This function does not do anything if there is no [Job] in the scope's [coroutineContext][CoroutineScope.coroutineContext].
320
+ * Coroutine cancallation [is cooperative](https://kotlinlang.org/docs/cancellation-and-timeouts.html#cancellation-is-cooperative)
321
+ * and normally, it's checked if a coroutine is cancelled when it *suspends*, for example,
322
+ * when trying to read from a [channel][kotlinx.coroutines.channels.Channel] that is empty.
323
+ *
324
+ * Sometimes, a coroutine does not need to perform suspending operations, but still wants to be cooperative
325
+ * and respect cancellation.
300
326
*
301
- * This method is a drop-in replacement for the following code, but with more precise exception:
327
+ * [ensureActive] function is inteded to be used for these scenarios and immediately bubble up the cancellation exception:
302
328
* ```
303
- * if (!isActive) {
304
- * throw CancellationException()
329
+ * val watchdogDispatcher = Dispatchers.IO.limitParallelism(1)
330
+ * fun backgroundWork() {
331
+ * println("Doing bookkeeping in the background in a non-suspending manner")
332
+ * Thread.sleep(100L) // Sleep 100ms
333
+ * }
334
+ * fun postBackgroundCleanup() = println("Doing something else")
335
+ * // Part of some non-trivial CoroutineScope-confined lifecycle
336
+ * launch(watchdogDispatcher) {
337
+ * while (true) {
338
+ * // Repeatatively do some background work that is non-suspending
339
+ * backgroundWork()
340
+ * ensureActive() // Bail out if the scope was cancelled
341
+ * postBackgroundCleanup() // Won't be invoked if the scope was cancelled
342
+ * }
305
343
* }
306
344
* ```
345
+ * This function does not do anything if there is no [Job] in the scope's [coroutineContext][CoroutineScope.coroutineContext].
307
346
*
347
+ * @see CoroutineScope.isActive
308
348
* @see CoroutineContext.ensureActive
309
349
*/
310
350
public fun CoroutineScope.ensureActive (): Unit = coroutineContext.ensureActive()
311
351
312
-
313
352
/* *
314
353
* Returns the current [CoroutineContext] retrieved by using [kotlin.coroutines.coroutineContext].
315
354
* This function is an alias to avoid name clash with [CoroutineScope.coroutineContext]:
0 commit comments