简体   繁体   中英

Which Coroutine Dispatcher to use for running code in a loop

In my Android application, I have a usecase in which I need to run a bit of code inside a loop for as long as the app is running.

Example code:

  fun exampleRunCodeInLoop() {
    viewModelScope.launch(Dispatchers.Default) { 
      while (true) {
        delay(5000) // Wait for 5 seconds
        // @param someCondition is just an example for the if statement
        if (someCondition == true) {
          withContext(Dispatchers.Main) {
            // Do something on Main thread
          }
        }
      }
    }
  }

I am confused regarding which Dispatcher to use for the launch block to get the best performance. Should I use Default , IO or just run everything on Main ?

Dispatchers.Default as it is designed to be optimal for computations, by using a shared pool of threads that contains a maximum number of threads that is equal to the number of CPU cores

Dispatchers.IO in case your blocking the thread, waiting for a response without doing heavy computational logic

At least here's the usage I did with coroutine dispatcher.

Dispatchers.Default - I usually use this when only doing CPU-intensive tasks to parallel with the current task on the main thread, it has a fixed size hardcoded to the number of available processors, because that's what makes sense for CPU-intensive tasks. Use with operation like loops, math operations, data/image manipulations.

Dispatchers.IO - is designed for offloading blocking IO tasks to a shared pool of threads. Use if you still need more threads than cores if you're doing blocking IO, eg, Database query is an IO operation or network calls

Dispatchers.Main - A coroutine dispatcher that is confined to the Main thread operating with UI objects. This dispatcher can be used either directly or via MainScope factory. Usually such dispatcher is single-threaded. Usually used when you are done or finished with the background task from IO or Default to forecast whatever results from operations you've done to the UI or Main Thread.

  • If you are doing IO, use the IO one
  • If you are doing something CPU intensive, use the Default one

In your code example that does not do heavy computation or IO, there is nothing that blocks, so you can launch in Dispatchers.Main and never have to switch contexts for anything. delay is a suspend function, so it doesn't block. You never have to worry about which dispatcher you're on when you call a suspend function (unless someone doesn't know what they're doing and has composed a suspend function that does block).

If you were not doing everything on the Main thread, you'd be switching back and forth between dispatchers anyway so it doesn't matter which Dispatcher you launch in as long as you wrap the appropriate sections in withContext and use the appropriate dispatcher. A general convention is if your coroutine interacts with the UI, launch it in Main and wrap the non-main parts. This follows the convention of all the non-coroutine code in Android which is written to be called from the main thread in the majority of methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM