Exerosis
06/18/2022, 4:50 PMwithContext(Dispatchers.Unconfined) {
println(1)
withContext(Dispatchers.Unconfined) { // Nested unconfined
println(2)
}
println(3)
}
println("Done")
Not always print 1, 2, 3 shouldn't the existence of the unconfined dispatcher have 0 impact on a block of code that doesn't make suspending calls? Is it possible for withContext to modify the way something executes if you aren't inserting a different dispatcher?
What is the meaning of: The invocation of cancel with exception (other than CancellationException) on this supervisor job also cancels parent.
Isn't is the case that every "well formed" call to cancel has either a CancellationException or null? Does that mean cancel() doesn't cancel parent but cancel(CancellationException()) does? Is that a standard understanding for jobs?
Very much struggling to understand how to adapt all of this to my system in an "idiomatic" way.Nick Allen
06/18/2022, 7:30 PMExerosis
06/22/2022, 12:59 AMspecialCancellableButtonOrSomething.onClick { event ->
if (!runBlocking(Dispatchers.Main) { someCallbackOrSomething() })
event.cancel()
}
Because the button onClick is on the main thread and so if we dispatch is going to schedule a task rather than running the task right away on the current thread (immediate) then until the onClick listener returns the someCallbackOrSomething() cannot be dispatched... However the onClick listener cannot return until after it has been (deadlock).
Couldn't you just give dispatchers canYield and yield() or just yield and they suspendUninterceptedOrReturn where they internally return if they cannot yield and suspend if they can? IG I still don't understand properly or something.
Ah yes launch would make more sense. If I understand correctly the thread responsible for running launched tasks is either what thread resumes the withContext, or the thread that called launch.
Thanks again!Nick Allen
06/22/2022, 2:09 AMval result = myScope.async(start = CoroutineState.Lazy) { //doesn't run
println("running")
delay(100)
42
}
delay(1000) //still doesn't run
println("result=${result.await()}") //now it'll start, wait 100, and then we'll print "result=42" 1100 millis after the coroutine was created
println("again, result=${result.await()}") //Will print immediately, it only runs once
Undispatched is more of an optimization, to avoid unnecessary thread switches. It takes extra time to schedule and wait for the scheduled task to actually run. It's extra convenient when you know you are already on the dispatcher you want.
You should not be calling runBlocking
from a click listener. It blocks which you should never do on main thread. Even if passing in other dispatchers. You can launch a coroutine using Dispatchers.Main and then you get the benefits of coroutines and can modify UI elements. runBlocking is more for APIs like OkHttp that have a private thread pool and then invoke callbacks on that thread pool expecting you to block so runBlocking is ok.
Of course they could have designed yield differently to always suspend ... but why? It does what it's supposed to do which is pass control back to the dispatcher. If you describe your usecase, then I can probably redirect you to the right API to use.Exerosis
06/23/2022, 1:11 AMNick Allen
06/23/2022, 3:51 AMrunBlocking
as it is for Future.get
.