Hey everyone, I’m having some issues finding some ...
# coroutines
a
Hey everyone, I’m having some issues finding some way to do something similar to DispatchQueue in Swift What I want to do is launch one coroutine off the main thread with the first queue element and when it’s done, launch the next in queue. I could implement something with async and all that, but I was wondering if there’s anything that already exists to support this behaviour?
z
Nothing in the core coroutines libraries that i know of. There’s been some talk about potentially including some sort of worker pool abstraction in the future, which is similar to this i think, but nothing yet
I wouldn’t use async, i’d just use a channel:
Copy code
private val tasks = Channel<suspend () -> Unit>(UNLIMITED)

fun enqueueTask(task: suspend () -> Unit) { tasks.offer(task) }

suspend fun run() {
  tasks.consumeEach { task ->
    task()
  }
}
a
That’s really nice, I didn’t know about Channel, thanks for the help!
b
I mean, if you are talking about doing work sequentially from items in a queue, you can do something such as:
Copy code
fun main() {
  scope.launch(Dispatchers.Main) {
    dataList().forEach { item ->
      withContext(Dispatchers.Default) {
        doWorkWith(item)
      }
    }
  }
}
That will launch a new coroutine that iterates through each item in a queue (list) on the main thread, and performs work on it in a background thread (computation).
z
Yes, but if that list isn’t thread safe you could have issues. Channels are effectively blocking queues and thread safe
b
If that is a concern, making the list a
flow
and doing the work on an
onEach
block is essentially the same as using a Channel.
z
if you subscribe early enough, and by
flow
you mean
MutableSharedFlow
, then yes
b
I just realized that
DispatchQueue
is conceptually a
Channel
in iOS. I was thinking it was already a cold list of items, which is why I mentioned using flow with it. 😅 For those following along, if you have a cold list of items to run, you can do something such as
list.asFlow().onEach { withContext(<http://Dispatchers.IO|Dispatchers.IO>) { /*.. do work ..*/ } }.launchIn(scope)
to do work sequentially on another thread . You could also use
MutableSharedFlow
to send items to a flow and have them run sequentially, and can be multi-cast. Just be aware of the back pressure strategy you use.
👍 1
However, Zach is right.
Channel
would be the closest to
DispatchQueue
.