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
.GlobalScope
(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