Whats the concept behind a CoroutineScope?
up vote
4
down vote
favorite
After reading the introduction and the javadoc of CoroutineScope I'm still a little confused what the idea behind a CoroutineScope
is.
The first sentence of the doc "Defines a scope for new coroutines." is not clear to me: Why do my coroutines need a scope?
Also, why are standalone coroutine builders deprecated? Why is it better to do this:
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
for (x in 1..5) send(x * x)
}
instead of
fun produceSquares(): ReceiveChannel<Int> = produce { //no longer an extension function
for (x in 1..5) send(x * x)
}
kotlin kotlinx.coroutines
add a comment |
up vote
4
down vote
favorite
After reading the introduction and the javadoc of CoroutineScope I'm still a little confused what the idea behind a CoroutineScope
is.
The first sentence of the doc "Defines a scope for new coroutines." is not clear to me: Why do my coroutines need a scope?
Also, why are standalone coroutine builders deprecated? Why is it better to do this:
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
for (x in 1..5) send(x * x)
}
instead of
fun produceSquares(): ReceiveChannel<Int> = produce { //no longer an extension function
for (x in 1..5) send(x * x)
}
kotlin kotlinx.coroutines
I found the description in this github issue useful to read: github.com/Kotlin/kotlinx.coroutines/issues/410. As explained there, "... coroutine builders likelaunch { ... }
andasync { ... }
start a global coroutine by default... This seems to be a wrong default. Global coroutines are error-prone." Now you can still do the same as the old behaviour if you want, by usingGlobalScope
, but it means you're explicitly doing this instead of accidentally doing it. And it's recommended that in most cases you shouldn't useGlobalScope
– Yoni Gibbs
Nov 21 at 13:42
To cancel the job's children
– EpicPandaForce
Nov 22 at 21:03
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
After reading the introduction and the javadoc of CoroutineScope I'm still a little confused what the idea behind a CoroutineScope
is.
The first sentence of the doc "Defines a scope for new coroutines." is not clear to me: Why do my coroutines need a scope?
Also, why are standalone coroutine builders deprecated? Why is it better to do this:
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
for (x in 1..5) send(x * x)
}
instead of
fun produceSquares(): ReceiveChannel<Int> = produce { //no longer an extension function
for (x in 1..5) send(x * x)
}
kotlin kotlinx.coroutines
After reading the introduction and the javadoc of CoroutineScope I'm still a little confused what the idea behind a CoroutineScope
is.
The first sentence of the doc "Defines a scope for new coroutines." is not clear to me: Why do my coroutines need a scope?
Also, why are standalone coroutine builders deprecated? Why is it better to do this:
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
for (x in 1..5) send(x * x)
}
instead of
fun produceSquares(): ReceiveChannel<Int> = produce { //no longer an extension function
for (x in 1..5) send(x * x)
}
kotlin kotlinx.coroutines
kotlin kotlinx.coroutines
edited Nov 21 at 14:41
Marko Topolnik
144k18193320
144k18193320
asked Nov 21 at 13:15
morpheus05
3,51122035
3,51122035
I found the description in this github issue useful to read: github.com/Kotlin/kotlinx.coroutines/issues/410. As explained there, "... coroutine builders likelaunch { ... }
andasync { ... }
start a global coroutine by default... This seems to be a wrong default. Global coroutines are error-prone." Now you can still do the same as the old behaviour if you want, by usingGlobalScope
, but it means you're explicitly doing this instead of accidentally doing it. And it's recommended that in most cases you shouldn't useGlobalScope
– Yoni Gibbs
Nov 21 at 13:42
To cancel the job's children
– EpicPandaForce
Nov 22 at 21:03
add a comment |
I found the description in this github issue useful to read: github.com/Kotlin/kotlinx.coroutines/issues/410. As explained there, "... coroutine builders likelaunch { ... }
andasync { ... }
start a global coroutine by default... This seems to be a wrong default. Global coroutines are error-prone." Now you can still do the same as the old behaviour if you want, by usingGlobalScope
, but it means you're explicitly doing this instead of accidentally doing it. And it's recommended that in most cases you shouldn't useGlobalScope
– Yoni Gibbs
Nov 21 at 13:42
To cancel the job's children
– EpicPandaForce
Nov 22 at 21:03
I found the description in this github issue useful to read: github.com/Kotlin/kotlinx.coroutines/issues/410. As explained there, "... coroutine builders like
launch { ... }
and async { ... }
start a global coroutine by default... This seems to be a wrong default. Global coroutines are error-prone." Now you can still do the same as the old behaviour if you want, by using GlobalScope
, but it means you're explicitly doing this instead of accidentally doing it. And it's recommended that in most cases you shouldn't use GlobalScope
– Yoni Gibbs
Nov 21 at 13:42
I found the description in this github issue useful to read: github.com/Kotlin/kotlinx.coroutines/issues/410. As explained there, "... coroutine builders like
launch { ... }
and async { ... }
start a global coroutine by default... This seems to be a wrong default. Global coroutines are error-prone." Now you can still do the same as the old behaviour if you want, by using GlobalScope
, but it means you're explicitly doing this instead of accidentally doing it. And it's recommended that in most cases you shouldn't use GlobalScope
– Yoni Gibbs
Nov 21 at 13:42
To cancel the job's children
– EpicPandaForce
Nov 22 at 21:03
To cancel the job's children
– EpicPandaForce
Nov 22 at 21:03
add a comment |
3 Answers
3
active
oldest
votes
up vote
3
down vote
You can still use global "standalone" coroutines by spawning them in GlobalScope
:
GlobalScope.launch {
println("I'm running unstructured")
}
However, it's not recommended to do this since creating coroutines on a global scope is basically the same we did with good old threads. You create them but somehow need to keep track of a reference to later join/cancel them.
Using structured concurrency, that is nesting coroutines in their scopes, you will have a more maintainable system overall. For example, if you spawn a coroutine inside another one, you inherit the outer scope. This has multiple advantages. If you cancel the outer coroutine, the cancellation will be delegated to its inner coroutines. Also, you can be sure that the outer coroutine will not complete before all its children coroutines have done their work.
There's also a very good example shown in the documentation for CoroutineScope
.
CoroutineScope should be implemented on entities with well-defined lifecycle that are responsible for launching children coroutines. Example of such entity on Android is Activity.
After all, the first version of your shown produceSquares
methods is better as it is only executable if invoked in a CoroutineScope
. That means you can run it inside any other coroutine:
launch {
produceSquares()
}
The coroutine created inside produceSquares
inherits the scope of launch
. You can be sure that launch
does not complete before produceSquares
. Also, if you cancelled launch
, this would also effect produceSquares
.
Furthermore, you can still create a globally running coroutine like this:
GlobalScope.produceSquares()
But, as mentioned, that's not the best option in most cases.
I'd also like to promote an article I wrote. There are some examples demonstrating what scopes mean: https://kotlinexpertise.com/kotlin-coroutines-concurrency/
I'm still unsure what the actual Job of a Scope is in relation to a coroutine. Its lifetime and job handling? Association with the actual threads (I mean in the end, code has to be executed by a thread, so someone, somehow needs to decide on which thread a coroutine needs to be executed)
– morpheus05
Nov 21 at 13:53
It’s about a coroutine‘s lifecycle in the end. TheCoroutineDispatcher
(just one part of theCoroutineScope
) defines what threads to run on. You can for example saylaunch(Dispatchers.Default)
to specify a dispatcher. Otherwise, you inherit from the outer scope
– s1m0nw1
Nov 21 at 14:00
@morpheus05 Don't forget that the same coroutine can pass from thread to thread, there is no single decision on which thread it will run. While it's suspended, it's not assigned to any thread, and a new decision is made each time it resumes. You can also switch threads without suspending, usingwithContext
. The best mental model to use is that a coroutine's "substrate" on which it runs is a thread, just like a CPU core is the substrate on which a thread runs.
– Marko Topolnik
Nov 21 at 14:46
If I look at the CoroutineScope its an interface with one field, coroutineContext: CoroutineContext. But why then this interface? Can the context change during the lifecycle of a scope? Why was this interface introduced and lets say we would only work with CoroutineContext?
– morpheus05
Nov 21 at 19:46
add a comment |
up vote
2
down vote
It is related to the concept of structured concurrency, which defines a structure between coroutines.
On a more philosophical level, you rarely launch coroutines “globally”, like you do with threads. Coroutines are always related to some local scope in your application, which is an entity with a limited life-time, like a UI element. So, with structured concurrency we now require that launch is invoked in a CoroutineScope, which is an interface implemented by your life-time limited objects (like UI elements or their corresponding view models).
As an evident consequence of this concept: by cancel
ling the context of a scope
, all it's subcoroutines will be canceled, too.
add a comment |
up vote
0
down vote
This kotlinconf presentation presents an explanation of how coroutinesscope provide a useful failure domain, and also best practice conventions for defining your own methods.
https://speakerdeck.com/elizarov/kotlin-coroutines-in-practice-at-kotlinconf-2018
https://www.youtube.com/watch?v=a3agLJQ6vt8
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
You can still use global "standalone" coroutines by spawning them in GlobalScope
:
GlobalScope.launch {
println("I'm running unstructured")
}
However, it's not recommended to do this since creating coroutines on a global scope is basically the same we did with good old threads. You create them but somehow need to keep track of a reference to later join/cancel them.
Using structured concurrency, that is nesting coroutines in their scopes, you will have a more maintainable system overall. For example, if you spawn a coroutine inside another one, you inherit the outer scope. This has multiple advantages. If you cancel the outer coroutine, the cancellation will be delegated to its inner coroutines. Also, you can be sure that the outer coroutine will not complete before all its children coroutines have done their work.
There's also a very good example shown in the documentation for CoroutineScope
.
CoroutineScope should be implemented on entities with well-defined lifecycle that are responsible for launching children coroutines. Example of such entity on Android is Activity.
After all, the first version of your shown produceSquares
methods is better as it is only executable if invoked in a CoroutineScope
. That means you can run it inside any other coroutine:
launch {
produceSquares()
}
The coroutine created inside produceSquares
inherits the scope of launch
. You can be sure that launch
does not complete before produceSquares
. Also, if you cancelled launch
, this would also effect produceSquares
.
Furthermore, you can still create a globally running coroutine like this:
GlobalScope.produceSquares()
But, as mentioned, that's not the best option in most cases.
I'd also like to promote an article I wrote. There are some examples demonstrating what scopes mean: https://kotlinexpertise.com/kotlin-coroutines-concurrency/
I'm still unsure what the actual Job of a Scope is in relation to a coroutine. Its lifetime and job handling? Association with the actual threads (I mean in the end, code has to be executed by a thread, so someone, somehow needs to decide on which thread a coroutine needs to be executed)
– morpheus05
Nov 21 at 13:53
It’s about a coroutine‘s lifecycle in the end. TheCoroutineDispatcher
(just one part of theCoroutineScope
) defines what threads to run on. You can for example saylaunch(Dispatchers.Default)
to specify a dispatcher. Otherwise, you inherit from the outer scope
– s1m0nw1
Nov 21 at 14:00
@morpheus05 Don't forget that the same coroutine can pass from thread to thread, there is no single decision on which thread it will run. While it's suspended, it's not assigned to any thread, and a new decision is made each time it resumes. You can also switch threads without suspending, usingwithContext
. The best mental model to use is that a coroutine's "substrate" on which it runs is a thread, just like a CPU core is the substrate on which a thread runs.
– Marko Topolnik
Nov 21 at 14:46
If I look at the CoroutineScope its an interface with one field, coroutineContext: CoroutineContext. But why then this interface? Can the context change during the lifecycle of a scope? Why was this interface introduced and lets say we would only work with CoroutineContext?
– morpheus05
Nov 21 at 19:46
add a comment |
up vote
3
down vote
You can still use global "standalone" coroutines by spawning them in GlobalScope
:
GlobalScope.launch {
println("I'm running unstructured")
}
However, it's not recommended to do this since creating coroutines on a global scope is basically the same we did with good old threads. You create them but somehow need to keep track of a reference to later join/cancel them.
Using structured concurrency, that is nesting coroutines in their scopes, you will have a more maintainable system overall. For example, if you spawn a coroutine inside another one, you inherit the outer scope. This has multiple advantages. If you cancel the outer coroutine, the cancellation will be delegated to its inner coroutines. Also, you can be sure that the outer coroutine will not complete before all its children coroutines have done their work.
There's also a very good example shown in the documentation for CoroutineScope
.
CoroutineScope should be implemented on entities with well-defined lifecycle that are responsible for launching children coroutines. Example of such entity on Android is Activity.
After all, the first version of your shown produceSquares
methods is better as it is only executable if invoked in a CoroutineScope
. That means you can run it inside any other coroutine:
launch {
produceSquares()
}
The coroutine created inside produceSquares
inherits the scope of launch
. You can be sure that launch
does not complete before produceSquares
. Also, if you cancelled launch
, this would also effect produceSquares
.
Furthermore, you can still create a globally running coroutine like this:
GlobalScope.produceSquares()
But, as mentioned, that's not the best option in most cases.
I'd also like to promote an article I wrote. There are some examples demonstrating what scopes mean: https://kotlinexpertise.com/kotlin-coroutines-concurrency/
I'm still unsure what the actual Job of a Scope is in relation to a coroutine. Its lifetime and job handling? Association with the actual threads (I mean in the end, code has to be executed by a thread, so someone, somehow needs to decide on which thread a coroutine needs to be executed)
– morpheus05
Nov 21 at 13:53
It’s about a coroutine‘s lifecycle in the end. TheCoroutineDispatcher
(just one part of theCoroutineScope
) defines what threads to run on. You can for example saylaunch(Dispatchers.Default)
to specify a dispatcher. Otherwise, you inherit from the outer scope
– s1m0nw1
Nov 21 at 14:00
@morpheus05 Don't forget that the same coroutine can pass from thread to thread, there is no single decision on which thread it will run. While it's suspended, it's not assigned to any thread, and a new decision is made each time it resumes. You can also switch threads without suspending, usingwithContext
. The best mental model to use is that a coroutine's "substrate" on which it runs is a thread, just like a CPU core is the substrate on which a thread runs.
– Marko Topolnik
Nov 21 at 14:46
If I look at the CoroutineScope its an interface with one field, coroutineContext: CoroutineContext. But why then this interface? Can the context change during the lifecycle of a scope? Why was this interface introduced and lets say we would only work with CoroutineContext?
– morpheus05
Nov 21 at 19:46
add a comment |
up vote
3
down vote
up vote
3
down vote
You can still use global "standalone" coroutines by spawning them in GlobalScope
:
GlobalScope.launch {
println("I'm running unstructured")
}
However, it's not recommended to do this since creating coroutines on a global scope is basically the same we did with good old threads. You create them but somehow need to keep track of a reference to later join/cancel them.
Using structured concurrency, that is nesting coroutines in their scopes, you will have a more maintainable system overall. For example, if you spawn a coroutine inside another one, you inherit the outer scope. This has multiple advantages. If you cancel the outer coroutine, the cancellation will be delegated to its inner coroutines. Also, you can be sure that the outer coroutine will not complete before all its children coroutines have done their work.
There's also a very good example shown in the documentation for CoroutineScope
.
CoroutineScope should be implemented on entities with well-defined lifecycle that are responsible for launching children coroutines. Example of such entity on Android is Activity.
After all, the first version of your shown produceSquares
methods is better as it is only executable if invoked in a CoroutineScope
. That means you can run it inside any other coroutine:
launch {
produceSquares()
}
The coroutine created inside produceSquares
inherits the scope of launch
. You can be sure that launch
does not complete before produceSquares
. Also, if you cancelled launch
, this would also effect produceSquares
.
Furthermore, you can still create a globally running coroutine like this:
GlobalScope.produceSquares()
But, as mentioned, that's not the best option in most cases.
I'd also like to promote an article I wrote. There are some examples demonstrating what scopes mean: https://kotlinexpertise.com/kotlin-coroutines-concurrency/
You can still use global "standalone" coroutines by spawning them in GlobalScope
:
GlobalScope.launch {
println("I'm running unstructured")
}
However, it's not recommended to do this since creating coroutines on a global scope is basically the same we did with good old threads. You create them but somehow need to keep track of a reference to later join/cancel them.
Using structured concurrency, that is nesting coroutines in their scopes, you will have a more maintainable system overall. For example, if you spawn a coroutine inside another one, you inherit the outer scope. This has multiple advantages. If you cancel the outer coroutine, the cancellation will be delegated to its inner coroutines. Also, you can be sure that the outer coroutine will not complete before all its children coroutines have done their work.
There's also a very good example shown in the documentation for CoroutineScope
.
CoroutineScope should be implemented on entities with well-defined lifecycle that are responsible for launching children coroutines. Example of such entity on Android is Activity.
After all, the first version of your shown produceSquares
methods is better as it is only executable if invoked in a CoroutineScope
. That means you can run it inside any other coroutine:
launch {
produceSquares()
}
The coroutine created inside produceSquares
inherits the scope of launch
. You can be sure that launch
does not complete before produceSquares
. Also, if you cancelled launch
, this would also effect produceSquares
.
Furthermore, you can still create a globally running coroutine like this:
GlobalScope.produceSquares()
But, as mentioned, that's not the best option in most cases.
I'd also like to promote an article I wrote. There are some examples demonstrating what scopes mean: https://kotlinexpertise.com/kotlin-coroutines-concurrency/
edited Nov 22 at 20:58
answered Nov 21 at 13:43
s1m0nw1
24k53797
24k53797
I'm still unsure what the actual Job of a Scope is in relation to a coroutine. Its lifetime and job handling? Association with the actual threads (I mean in the end, code has to be executed by a thread, so someone, somehow needs to decide on which thread a coroutine needs to be executed)
– morpheus05
Nov 21 at 13:53
It’s about a coroutine‘s lifecycle in the end. TheCoroutineDispatcher
(just one part of theCoroutineScope
) defines what threads to run on. You can for example saylaunch(Dispatchers.Default)
to specify a dispatcher. Otherwise, you inherit from the outer scope
– s1m0nw1
Nov 21 at 14:00
@morpheus05 Don't forget that the same coroutine can pass from thread to thread, there is no single decision on which thread it will run. While it's suspended, it's not assigned to any thread, and a new decision is made each time it resumes. You can also switch threads without suspending, usingwithContext
. The best mental model to use is that a coroutine's "substrate" on which it runs is a thread, just like a CPU core is the substrate on which a thread runs.
– Marko Topolnik
Nov 21 at 14:46
If I look at the CoroutineScope its an interface with one field, coroutineContext: CoroutineContext. But why then this interface? Can the context change during the lifecycle of a scope? Why was this interface introduced and lets say we would only work with CoroutineContext?
– morpheus05
Nov 21 at 19:46
add a comment |
I'm still unsure what the actual Job of a Scope is in relation to a coroutine. Its lifetime and job handling? Association with the actual threads (I mean in the end, code has to be executed by a thread, so someone, somehow needs to decide on which thread a coroutine needs to be executed)
– morpheus05
Nov 21 at 13:53
It’s about a coroutine‘s lifecycle in the end. TheCoroutineDispatcher
(just one part of theCoroutineScope
) defines what threads to run on. You can for example saylaunch(Dispatchers.Default)
to specify a dispatcher. Otherwise, you inherit from the outer scope
– s1m0nw1
Nov 21 at 14:00
@morpheus05 Don't forget that the same coroutine can pass from thread to thread, there is no single decision on which thread it will run. While it's suspended, it's not assigned to any thread, and a new decision is made each time it resumes. You can also switch threads without suspending, usingwithContext
. The best mental model to use is that a coroutine's "substrate" on which it runs is a thread, just like a CPU core is the substrate on which a thread runs.
– Marko Topolnik
Nov 21 at 14:46
If I look at the CoroutineScope its an interface with one field, coroutineContext: CoroutineContext. But why then this interface? Can the context change during the lifecycle of a scope? Why was this interface introduced and lets say we would only work with CoroutineContext?
– morpheus05
Nov 21 at 19:46
I'm still unsure what the actual Job of a Scope is in relation to a coroutine. Its lifetime and job handling? Association with the actual threads (I mean in the end, code has to be executed by a thread, so someone, somehow needs to decide on which thread a coroutine needs to be executed)
– morpheus05
Nov 21 at 13:53
I'm still unsure what the actual Job of a Scope is in relation to a coroutine. Its lifetime and job handling? Association with the actual threads (I mean in the end, code has to be executed by a thread, so someone, somehow needs to decide on which thread a coroutine needs to be executed)
– morpheus05
Nov 21 at 13:53
It’s about a coroutine‘s lifecycle in the end. The
CoroutineDispatcher
(just one part of the CoroutineScope
) defines what threads to run on. You can for example say launch(Dispatchers.Default)
to specify a dispatcher. Otherwise, you inherit from the outer scope– s1m0nw1
Nov 21 at 14:00
It’s about a coroutine‘s lifecycle in the end. The
CoroutineDispatcher
(just one part of the CoroutineScope
) defines what threads to run on. You can for example say launch(Dispatchers.Default)
to specify a dispatcher. Otherwise, you inherit from the outer scope– s1m0nw1
Nov 21 at 14:00
@morpheus05 Don't forget that the same coroutine can pass from thread to thread, there is no single decision on which thread it will run. While it's suspended, it's not assigned to any thread, and a new decision is made each time it resumes. You can also switch threads without suspending, using
withContext
. The best mental model to use is that a coroutine's "substrate" on which it runs is a thread, just like a CPU core is the substrate on which a thread runs.– Marko Topolnik
Nov 21 at 14:46
@morpheus05 Don't forget that the same coroutine can pass from thread to thread, there is no single decision on which thread it will run. While it's suspended, it's not assigned to any thread, and a new decision is made each time it resumes. You can also switch threads without suspending, using
withContext
. The best mental model to use is that a coroutine's "substrate" on which it runs is a thread, just like a CPU core is the substrate on which a thread runs.– Marko Topolnik
Nov 21 at 14:46
If I look at the CoroutineScope its an interface with one field, coroutineContext: CoroutineContext. But why then this interface? Can the context change during the lifecycle of a scope? Why was this interface introduced and lets say we would only work with CoroutineContext?
– morpheus05
Nov 21 at 19:46
If I look at the CoroutineScope its an interface with one field, coroutineContext: CoroutineContext. But why then this interface? Can the context change during the lifecycle of a scope? Why was this interface introduced and lets say we would only work with CoroutineContext?
– morpheus05
Nov 21 at 19:46
add a comment |
up vote
2
down vote
It is related to the concept of structured concurrency, which defines a structure between coroutines.
On a more philosophical level, you rarely launch coroutines “globally”, like you do with threads. Coroutines are always related to some local scope in your application, which is an entity with a limited life-time, like a UI element. So, with structured concurrency we now require that launch is invoked in a CoroutineScope, which is an interface implemented by your life-time limited objects (like UI elements or their corresponding view models).
As an evident consequence of this concept: by cancel
ling the context of a scope
, all it's subcoroutines will be canceled, too.
add a comment |
up vote
2
down vote
It is related to the concept of structured concurrency, which defines a structure between coroutines.
On a more philosophical level, you rarely launch coroutines “globally”, like you do with threads. Coroutines are always related to some local scope in your application, which is an entity with a limited life-time, like a UI element. So, with structured concurrency we now require that launch is invoked in a CoroutineScope, which is an interface implemented by your life-time limited objects (like UI elements or their corresponding view models).
As an evident consequence of this concept: by cancel
ling the context of a scope
, all it's subcoroutines will be canceled, too.
add a comment |
up vote
2
down vote
up vote
2
down vote
It is related to the concept of structured concurrency, which defines a structure between coroutines.
On a more philosophical level, you rarely launch coroutines “globally”, like you do with threads. Coroutines are always related to some local scope in your application, which is an entity with a limited life-time, like a UI element. So, with structured concurrency we now require that launch is invoked in a CoroutineScope, which is an interface implemented by your life-time limited objects (like UI elements or their corresponding view models).
As an evident consequence of this concept: by cancel
ling the context of a scope
, all it's subcoroutines will be canceled, too.
It is related to the concept of structured concurrency, which defines a structure between coroutines.
On a more philosophical level, you rarely launch coroutines “globally”, like you do with threads. Coroutines are always related to some local scope in your application, which is an entity with a limited life-time, like a UI element. So, with structured concurrency we now require that launch is invoked in a CoroutineScope, which is an interface implemented by your life-time limited objects (like UI elements or their corresponding view models).
As an evident consequence of this concept: by cancel
ling the context of a scope
, all it's subcoroutines will be canceled, too.
answered Nov 21 at 13:23
Andrey Ilyunin
744219
744219
add a comment |
add a comment |
up vote
0
down vote
This kotlinconf presentation presents an explanation of how coroutinesscope provide a useful failure domain, and also best practice conventions for defining your own methods.
https://speakerdeck.com/elizarov/kotlin-coroutines-in-practice-at-kotlinconf-2018
https://www.youtube.com/watch?v=a3agLJQ6vt8
add a comment |
up vote
0
down vote
This kotlinconf presentation presents an explanation of how coroutinesscope provide a useful failure domain, and also best practice conventions for defining your own methods.
https://speakerdeck.com/elizarov/kotlin-coroutines-in-practice-at-kotlinconf-2018
https://www.youtube.com/watch?v=a3agLJQ6vt8
add a comment |
up vote
0
down vote
up vote
0
down vote
This kotlinconf presentation presents an explanation of how coroutinesscope provide a useful failure domain, and also best practice conventions for defining your own methods.
https://speakerdeck.com/elizarov/kotlin-coroutines-in-practice-at-kotlinconf-2018
https://www.youtube.com/watch?v=a3agLJQ6vt8
This kotlinconf presentation presents an explanation of how coroutinesscope provide a useful failure domain, and also best practice conventions for defining your own methods.
https://speakerdeck.com/elizarov/kotlin-coroutines-in-practice-at-kotlinconf-2018
https://www.youtube.com/watch?v=a3agLJQ6vt8
answered Nov 21 at 18:19
Yuri Schimke
3,14921221
3,14921221
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53412886%2fwhats-the-concept-behind-a-coroutinescope%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I found the description in this github issue useful to read: github.com/Kotlin/kotlinx.coroutines/issues/410. As explained there, "... coroutine builders like
launch { ... }
andasync { ... }
start a global coroutine by default... This seems to be a wrong default. Global coroutines are error-prone." Now you can still do the same as the old behaviour if you want, by usingGlobalScope
, but it means you're explicitly doing this instead of accidentally doing it. And it's recommended that in most cases you shouldn't useGlobalScope
– Yoni Gibbs
Nov 21 at 13:42
To cancel the job's children
– EpicPandaForce
Nov 22 at 21:03