Animesh Sahu
11/15/2019, 4:53 AMfun main() {
Foo()
}
class Foo {
val bar = Bar()
}
class Bar() {
// perform some long running tasks with some part dependent on foo
}
Case 1:
fun main = runBlocking { //this: CoroutineScope
Foo(this)
}
class Foo(scope: CoroutineScope): CoroutineScope by scope {
val bar = Bar(this)
}
class Bar(val foo: Foo): CoroutineScope by foo {
}
Case 2:
fun main = runBlocking { //this: CoroutineScope
Foo(this)
}
class Foo(scope: CoroutineScope): CoroutineScope {
override val coroutineContext = scope.coroutineContext
val bar = Bar(this)
}
class Bar(val foo: Foo): CoroutineScope {
override val coroutineContext = foo.coroutineContext
}
Case 3:
fun main() {
//just dont start coroutine here
Foo()
}
class Foo: CoroutineScope {
override val coroutineContext = Dispatchers.Default
val bar = Bar(this)
}
class Bar(foo: Foo): CoroutineScope {
override val coroutineContext = Dispatchers.Default
}
Or if there is a better way to create a coroutine driven application?bdawg.io
11/15/2019, 5:10 AMrunBlocking
and b) not having Foo and Bar implement CoroutineScope directly. For example: suspend fun main(): Unit = withContext(Dispatchers.Default) {
Foo(this)
}
class Foo(private val scope: CoroutineScope) {
val bar = Bar(scope)
}
class Bar(private val scope: CoroutineScope) {
}
And that's only if you have a reason to provide the scope down. In most cases, it's probably better just to define suspending functions and using the coroutineScope
coroutine builder. class Bar {
suspend fun doSomething() = coroutineScope {
val asyncOne = async { foo.doSomething(1) }
val asyncTwo = async { foo.doSomething(1) }
processResult(asyncOne, asyncTwo)
}
}
Animesh Sahu
11/15/2019, 5:15 AMsuspend fun main(): Unit = withContext(Dispatchers.Default) {
Foo(this)
}
fun main = runBlocking { //this: CoroutineScope
Foo(this)
}
bdawg.io
11/15/2019, 5:19 AMrunBlocking
blocks the current thread and provides it as the only thread backing the CoroutineScope.
withContext
, you're specifying the context (in this case the Default dispatcher to have more than one thread).
AFAIK, suspend fun main() { doSomething() }
is just a Kotlin compiler short-hand for fun main() { runBlocking { doSomething() } }
Zach Klippenstein (he/him) [MOD]
11/15/2019, 4:37 PMsuspend fun main
will start executing on the main thread, but if you look at coroutineContext
it’s EmptyCoroutineContext
, which implies Dispatchers.Default
, and any coroutines started from the scope will be executed on the default pool.
https://pl.kotl.in/HZUd3SohRbdawg.io
11/15/2019, 5:09 PMsuspend fun main() {
Foo(this).doSomething()
}
interesting!Dico
11/16/2019, 11:49 PMprivate val scope = GlobalScope + Job()
And then using scope
Animesh Sahu
11/17/2019, 3:08 PMbdawg.io
11/17/2019, 3:41 PMJob()
creates a job instance that you can use as a parent job to others. The +
is for the ContextElement
type, which allow you to merge multiple aspects of the coroutineContext
to provide the context that you want for your CoroutineScope
.bdawg.io
11/17/2019, 3:45 PMGlobalScope
(which is really just the EmptyCoroutineContext
) and his own parent job. I’d recommend being explicit about which dispatcher you want though.
private val scope = Dispatchers.Default + Job()
Animesh Sahu
11/18/2019, 11:24 AMbdawg.io
11/18/2019, 3:55 PMAnimesh Sahu
11/18/2019, 3:57 PMDico
11/19/2019, 4:33 AM