为后端应用程序设置Kotlin协程范围的正确方法

时间:2018-11-08 19:57:10

标签: kotlin kotlinx.coroutines

设置协程范围的正确方法是什么-

1。实施范围

@Service
class MyServiceImpl : MyService, CoroutineScope {
    private val job: Job = Job()
    override val coroutineContext: CoroutineContext
        get() = job + Executors.newFixedThreadPool(100).asCoroutineDispatcher()
    override fun get(): String {
        launch {....}
        return "Result"
    }}

` 2.不执行

@Service
class MyServiceImpl : MyService {
    private val scope = Executors.newFixedThreadPool(100).asCoroutineDispatcher()
    override fun get(): String {
        GlobalScope.launch(scope) {....}
        return "Result"
    }}

还是只在没有任何上下文的情况下使用GlobalScope?

1 个答案:

答案 0 :(得分:0)

没有正确的方法,这三种变体在不同的情况下都有用。

  1. 实施自己的协程范围: 如果协程的寿命取决于另一个对象的寿命。在UI应用程序中尤其有用,例如Android,如果您需要销毁所有待处理的协程,则在销毁启动活动时,请参见https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md#structured-concurrency-lifecycle-and-coroutine-parent-child-hierarchy
  2. 从线程池创建作用域:如果协程应在公共线程池中运行。在这种情况下,新协程的寿命不取决于该范围,而是取决于外部协程:

    val fixedThreadPoolContext = newFixedThreadPoolContext(100, "background")
    launch(Dispatchers.Main) {
        withContext(fixedThreadPoolContext) {
            //parent job is from the outer coroutine
        }
        //or
        val asyncResult = async(fixedThreadPoolContext) {
            //parent job is from the outer coroutine
        }
    }
    
  3. 使用全局范围:如果您要启动一些不依赖于其他对象的背景协程。通常,最好提供一个绑定到您的应用程序对象或某个全局单例的范围。然后,您可以提供自己的异常处理程序等

对于后端服务,我将使用自己的全局线程池分派器,然后您可以控制大小。请注意,GlobalScope使用CPU计数作为参数来定义池大小。这对CPU限制任务非常有用,但对IO任务(例如数据库访问)却不是。