I'm having a very hard time understanding the diff...
# coroutines
l
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
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:
Copy code
someContext.launch(someOtherContext)
vs
Copy code
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
I see, that made it really simple. Thank you.
t
@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
Copy code
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
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
CoroutineScope
is simply a way to implicitly pass down a
coroutineContext
(using a receiver).
m
@Dominaezzz then the question remains the same: Why not just use
CoroutineContext
as the receiver, as it would achieve the same result 😄
d
Ah good point. I just re-read what you wrote. I think I've just repeated what you said 😅 .
t
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
No,
Job()
cancels all and
SupervisorJob
only one, afaik.
👍 1
h
tldr:
CoroutineScope
is a sugar for working with
CoroutineContext
. Mainly for cancelling coroutines.