0

I'm trying to understand the difference between the 2.

If a CoroutineScope is not tied to any lifecycle-aware component, then I think they behave the same:

If Im not passing any context to CoroutineScope, then both would initialized with EmptyCoroutineContext, and thats practicaly means children has no parents, meaning they run totaly independently, and not even scope.cancel() actualy cancels them, and thats only happen when the whole app is closed. Am I missing something here ?

val scope = GlobalScope()
scope.launch {
    launch {
        println("job1 working")
    } 

     launch {
        println("job2 working")
    } 
}

scope.cancel() // no any effect
val scope = CoroutineScope(EmptyCoroutineContext)
...
scope.cancel()

If my understanding is correct, are there any example where they different ?

3 Answers 3

5

Yes, there are significant differences between GlobalScope and CoroutineScope in Kotlin coroutines.

GlobalScope is a top-level, lifecycle-unaware scope. Coroutines launched using GlobalScope.launch are not tied to any specific component or parent job and live as long as the entire application process runs.

GlobalScope.launch returns only a Job instance, not a scope. While calling cancel() on that job should cancel it and its child jobs, you may not observe the cancellation effect because each of those child jobs has already completed before the cancel() call takes effect.

You create a scope using CoroutineScope(EmptyCoroutineContext). Passing EmptyCoroutineContext means the scope uses the default dispatcher (Dispatchers.Default). Since this is a CoroutineScope, any coroutine launched with scope.launch can be cancelled by calling scope.cancel().

Sign up to request clarification or add additional context in comments.

3 Comments

Yeah, but here I passing empty context to the scope, not to launch, which should mean it defines the parent's context including dispatcher and job. Also, in the post is wrong (will fix), but the cancel intented to call on the scope, and not on launch, so like val scope = GlobalScope() val job = scope.launch What is not clear, that under the hood GlobalScope also uses CoroutineScope to create a scope, so essentialy created the same way, so what GlobalScope does differently then during creating it ?
It might seem the same because both use an empty context. But they work is different. GlobalScope doesn’t have a Job in the context. Means any coroutines you start with it run on their own and can’t be cancelled together. In fact, calling GlobalScope.cancel() doesn’t really do anything if you look at cancel method definition(no Job to cancel). When you create a CoroutineScope(EmptyCoroutineContext), It adds a new Job in its context behind the scenes. Now, every launch inside that scope is linked to that job. So if you call scope.cancel(), it cancels everything in the scope at once
I think my misunderstanding comes from that since all Job elements (including empty) has the same key (Job.Key), that newCoroutineContext (in launch) always overwrite a parent Job with provided by child context. But it that were the case, then parent-child relation could be never established. And that's why we shouldn't pass any job to launch, to prevent newCoroutineContex replace the parent's job, so parent-child is not broken. But i gueess i was wrong then
0

GlobalScope is designed for top-level, application-wide coroutines that are not tied to any component lifecycle. It should be used very sparingly, typically for background tasks that must survive across the whole app lifecycle.

5 Comments

but by default neither CoroutineScope tied to any lifecycle afaik, and under the hood isn't GlobalScope uses CoroutineScope, just does few thiungs differently?
Only if you explicitly construct a CoroutineScope with CoroutineScope(...). You shouldn't usually be doing that. Instead, you should be using the CoroutineScope you get automatically from being inside the braces of launch { ... }, async { ... }, coroutineScope { ... }, and so on.
Yeah, Im aware that. I mean I was just wondering why GlobalScope is always discouraged, while CoroutineScope isn’t. Since CoroutineScope requires a context to pass, and GlobalScope is initialized with an empty context, I assumed that if I also passed an empty context to a CoroutineScope, they would behave the same. But then I read that if a CoroutineScope is cancelled, its children are also cancelled, whereas if a GlobalScope coroutine is cancelled, its children aren’t.
But then I read that if a CoroutineScope is cancelled, its children are also cancelled, whereas if a GlobalScope coroutine is cancelled, its children aren’t. But then looking at newCoroutineContext, I started wondering how the parent-child relationship is actually established, and why does one cancel its children while the other doesn’t?
And another question would be why passing A scope'context to e.g GlobalScope.launch, then doing an A.cancel() not cancels all the coroutines started by the globalscope, if by passing anything to a launch should make that job to a parent to all coroutines inside globalscope. So altogether Im super confused
-2
GlobalScope CoroutineScope
tied to an entire application lifecycle tied to a specific component's lifecycle
cancellation is difficult and manual cancellation is easy and automatic

2 Comments

That's not true. What component do you think is val scope = CoroutineScope(...) tied to? The question explicitly asked about an un-tied scope: "[...] CoroutineScope is not tied to any lifecycle-aware component"
The reason my previous answer likely conflated CoroutineScope with lifecycles is because the most common and recommended use pattern is to bind a CoroutineScope to the lifecycle of a component. Frameworks like Android provide this for you automatically -> viewModelScope is a CoroutineScope that is automatically cancelled when the ViewModel is cleared, -> lifecycleScope is a CoroutineScope that is automatically cancelled when the LifecycleOwner (like an Activity or Fragment) is destroyed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.