BArtWell
BArtWell

Reputation: 4044

How to use actors to handle message frequently in a single thread?

I need to launch some code frequently in a single non-UI thread. I am trying to use actors to achieve it:

class SomeClass {

    @OptIn(ObsoleteCoroutinesApi::class)
    private fun CoroutineScope.myActor() = actor<MyMessage> {
        for (message in channel) {
            delay(5000)
            Log.d("SomeClass", "Message ${Thread.currentThread().name}")
        }
    }

    private var channel: SendChannel<MyMessage>? = null
    private val scope = CoroutineScope(Dispatchers.Default)

    fun send() {
        scope.launch {
                if (channel == null) {
                    channel = myActor()
                }
                channel?.send(IncCounter)
            }
    }

    sealed class MyMessage
}

And then calling it:

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)

    val c = SomeClass()
    c.send()
    c.send()
    c.send()
    c.send()       

}

Output:

Message DefaultDispatcher-worker-8
Message DefaultDispatcher-worker-2
Message DefaultDispatcher-worker-8
Message DefaultDispatcher-worker-2

So, as I see it creates more than one thread. How to implement frequently messaging handling in a single thread?

Upvotes: 0

Views: 54

Answers (1)

Sergio
Sergio

Reputation: 30655

Try to use limitedParallelism(1) function on CoroutineDispatcher:

private val scope = CoroutineScope(Dispatchers.Default.limitedParallelism(1))

OR

private fun CoroutineScope.myActor() = actor<MyMessage>(context = Dispatchers.Default.limitedParallelism(1)) { ... }

Upvotes: 2

Related Questions