https://kotlinlang.org logo
Title
l

Lulu

12/31/2019, 8:34 AM
I'm having a very hard time understanding the difference between
CoroutineContext
and
CoroutineScope
. I did my research and I also read this article by Elizarov: https://medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055 He says they're the same thing but they serve different purposes. He explains both of them in the article but he doesn't conclude. So what's the difference after all? I'm very confused. Just to clarify, I have been using coroutines since they were experimental so I'm not new to the concept, I just started questioning the difference between those two things that I interact with all the time. I know that a scope basically contains a context, but I still don't understand why scopes exist in the first place. Why not just contexts? Or what's the clear distinction between them? (e.g. "the purpose of
CoroutineContext
is ... while the purpose of
CoroutineScope
is ...") I feel I'm very close to the answer but I just can't put the pieces together.
👍 4
m

Marc Knaup

12/31/2019, 8:58 AM
Hmm, a potential issue with having
CoroutineContext
as receiver parameter: It’s methods (
get
,
fold
,
plus
,
minusKey
, etc.) would end up in the local scope (
this.…
) while
CoroutineScope
only has
.coroutineContext
and the launch functions, all of which are intended to be used in that case. Also the following would be a bit ambiguous:
someContext.launch(someOtherContext)
vs
someOtherContext.launch(someContext)
You can only have one scope to launch in, but you have two context that need to be merged somehow. I see it as:
CoroutineContext
configures the behavior of the coroutine and describes its… context.
CoroutineScope
simply declares what
CoroutineContext
is being used in the current scope.
👍 2
l

Lulu

12/31/2019, 9:03 AM
I see, that made it really simple. Thank you.
t

Thiyagu

12/31/2019, 10:57 AM
@Marc Knaup can you please explain how it behaves in below code? cancelling the job does it make both coroutine context to stop?https://gist.github.com/thiyagu06/9523339fd365017b7eb6051677df8416
private val supervisorJob = SupervisorJob()
     val fastProcessingContext: CoroutineContext = ....     
private val scope =CoroutineScope(supervisorJob + fastProcessingContext)
     val slowProcessingContext: CoroutineContext = ....
    
    fun startProcssing() {
      scope.launch {
        
        with(fastProcessingContext) {
            delay(500) //pretend fast processing I/O    
        }
        
        with(slowProcessingContext) {
            delay(1000)
        }
        
      }
      
    }
    
    fun stopProcessing() {
        supervisorJob.cancel()
    }
m

Marc Knaup

12/31/2019, 12:17 PM
A failure or cancellation of a child does not cause the supervisor job to fail and does not affect its other children, …
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-supervisor-job.html In your example however that’s irrelevant because you have to use
withContext
, not
with
. The latter does nothing in your example.
d

Dominaezzz

12/31/2019, 12:18 PM
CoroutineScope
is simply a way to implicitly pass down a
coroutineContext
(using a receiver).
m

Marc Knaup

12/31/2019, 12:18 PM
@Dominaezzz then the question remains the same: Why not just use
CoroutineContext
as the receiver, as it would achieve the same result 😄
d

Dominaezzz

12/31/2019, 12:21 PM
Ah good point. I just re-read what you wrote. I think I've just repeated what you said 😅 .
t

Thiyagu

12/31/2019, 12:58 PM
so, in my example
supervisorJob.cancel()
doesn't stop the coroutines? But if I use `supervisorJob.cancel()
withcontext
receiver, it will stop all the
coroutineContext
. Is that correct understanding?
m

Marc Knaup

12/31/2019, 1:02 PM
No,
Job()
cancels all and
SupervisorJob
only one, afaik.
👍 1
h

hmole

01/09/2020, 9:11 AM
tldr:
CoroutineScope
is a sugar for working with
CoroutineContext
. Mainly for cancelling coroutines.