elizarov
11/03/2018, 6:45 PMlouiscad
11/03/2018, 6:48 PMoshai
11/03/2018, 8:17 PMValV
11/03/2018, 8:47 PMMark
11/04/2018, 2:42 AMelizarov
11/04/2018, 4:40 AMjmfayard
11/04/2018, 5:59 AMMark
11/04/2018, 6:14 AMcoroutineScope{}
and withContext(dispatcher) {}
surrounding the main body?louiscad
11/04/2018, 6:15 AMwithContext
already creates a scope, no need for an additional one.Mark
11/04/2018, 6:16 AMwithContext()
will not return until all child jobs complete?coroutineScope{}
within a suspend function?louiscad
11/04/2018, 6:22 AMwithContext
gives you a scope as a receiver for le block you pass to it, but no, it only folds the context you pass to it with the current context, so it doesn't wait for any child coroutine you start (the parent scope will).
That said, I have never launched a coroutine from a withContext
block.elizarov
11/04/2018, 6:22 AMkotlinx.coroutines
library that accept a block with CoroutineScope
receiver do consistently wait for all children.louiscad
11/04/2018, 6:24 AMsuspend fun main() = coroutineScope {
withContext(Dispatchers.Default) {
println(1)
launch {
delay(1000)
println(2)
}
println(3)
}
println(4)
}
withContext
source code, I wasn't so sure, so I tried, and saw it creates no job that waits for child coroutines.elizarov
11/04/2018, 6:27 AMlouiscad
11/04/2018, 6:28 AM1
3
4
2
which shows that withContext
call resumes before its child coroutine is completed.elizarov
11/04/2018, 6:28 AMlouiscad
11/04/2018, 6:30 AMelizarov
11/04/2018, 6:31 AMlouiscad
11/04/2018, 6:31 AM1, 2, 3, 4
, it should print 1, 3, 2, 4
😉 I assume you mistyped itelizarov
11/04/2018, 6:35 AMMark
11/04/2018, 6:36 AMcoroutineScope{}
(instead of withContext()
) within suspend function? I guess when you don’t want to specify the Dispatcher
, but that seems oddelizarov
11/04/2018, 6:38 AMwithContext
but coroutineScope
Mark
11/04/2018, 6:40 AMlouiscad
11/04/2018, 6:44 AMwithContext
takes a parameter, coroutineScope
does not. I don't see how a lint check would/should assume that you should not call withContext
but use coroutineScope
instead.Mark
11/04/2018, 6:50 AMwithContext
and coroutineScope
seem to offer similar functionality. The key difference being the passed in dispatcher/context. In which case, one might think of those two functions being named the same with an optional dispatcher/context. In other words, being able to write coroutineScope(<http://Dispatcher.IO|Dispatcher.IO>){}
instead of withContext(<http://Disptacher.IO|Disptacher.IO>){}
Just cutting down the vocabulary.coroutineScope { <my suspending function calls> }
and I want to add a call to IO-blocking function (within that block), then I can do that and just add the (<http://Dispatcher.IO|Dispatcher.IO>)
argument to coroutineScope
louiscad
11/04/2018, 7:33 AMoperator fun invoke
thing never makes it into the library, then I think your coroutineScope(context: CoroutineContext = EmptyCoroutineContext) { … }
proposal is a good idea. Maybe you could create on issue for that on GitHub, @Mark?Mark
11/04/2018, 7:43 AMelizarov
11/04/2018, 8:08 AMMark
11/04/2018, 8:52 AMwithContext
for non-blocking code (e.g. withContext(Dispatchers.Main)
) when touching the UI? And couldn’t you also “decompose your code into multiple concurrent operations via launch or async” when using withContext()
as in the earlier 1, 3, 2, 4
example?louiscad
11/04/2018, 9:04 AMwithContext
, not runBlocking
, so the use cases go beyond just running blocking code off the calling thread. Usually, when you use Dispatcher.Main
, you use it as default dispatcher for the UI component root scope.Tolriq
11/04/2018, 12:25 PMelizarov
11/04/2018, 12:52 PMwithContext
to make life easier for consumers.Tolriq
11/04/2018, 12:56 PMelizarov
11/04/2018, 1:24 PMTolriq
11/04/2018, 1:26 PMelizarov
11/04/2018, 1:30 PMTolriq
11/04/2018, 1:34 PMTolriq
11/04/2018, 4:39 PM