简体   繁体   English

Kotlin 协程 - 使用协程范围/上下文的不同选项?

[英]Kotlin Coroutines - Different options for using Coroutine Scope/Context?

I'm new to Kotlin/Coroutines and I've noticed two different ways to use CoroutineScope .我是 Kotlin/Coroutines 的新手,我注意到使用CoroutineScope两种不同方式。

Option 1 is as follows, within any function:选项 1 如下,在任何函数中:

CoroutineScope(Dispatchers.Default).launch { 
    expensiveOperation() 
}

Option 2 is by implementing the CoroutineScope interface in your class, overriding the CoroutineContext , and then you can just launch coroutines easily with launch or async :选项 2 是通过在您的类中实现CoroutineScope接口,覆盖CoroutineContext ,然后您可以使用launchasync轻松启动协程:

@Service
class ServiceImpl() : CoroutineScope {

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Default + Job()

    fun someFunction() {
        launch {
            expensiveOperation()
        }
    }
}

I am currently developing a backend endpoint that will do the following:我目前正在开发一个后端端点,它将执行以下操作:

  1. take a request接受请求
  2. save the request context to a database将请求上下文保存到数据库
  3. launch a non blocking coroutine in the background to perform an expensive/lengthy operation on the request, and immediately return an http 200. (essentially, once we have the context saved, we can return a response and let the request process in the background)在后台启动一个非阻塞协程对请求执行一个昂贵/冗长的操作,并立即返回一个http 200。(本质上,一旦我们保存了上下文,我们就可以返回一个响应并让请求在后台处理)

What is the difference in the two use cases, and for this scenario, which is the preferred method for obtaining a CoroutineScope ?这两个用例有什么区别,对于这个场景,哪个是获取CoroutineScope的首选方法?

This endpoint may receive multiple requests per second, and the lengthy operation will take a minute or two, so there will definitely be multiple requests processing at the same time, originating from various requests.这个端点每秒可能会收到多个请求,冗长的操作需要一两分钟,所以肯定会有多个请求同时处理,来自各种请求。

Also, if it's option 2, do I want to pass the scope/context to the function that does the heavy processing?另外,如果是选项 2,我是否要将范围/上下文传递给执行繁重处理的函数? Or is that unnecessary?或者这是不必要的? For example:例如:

class ServiceImpl() : CoroutineScope {类 ServiceImpl() : CoroutineScope {

override val coroutineContext: CoroutineContext
    get() = Dispatchers.Default + Job()

fun someFunction() {
    launch {
        expensiveOperation(CoroutineScope(coroutineContext))
    }
}

private fun expensiveOperation(scope: CoroutineScope) 
    {
        // perform expensive operation
    }

} }

This is a Spring Boot app, and I'm using version 1.3 of Kotlin .这是一个 Spring Boot 应用程序,我使用的是Kotlin 1.3版。

Please let me know if you have any thoughts/suggestions on how to best structure this service class.如果您对如何最好地构建此服务类有任何想法/建议,请告诉我。 Thanks谢谢

I would recommend option 2. It will give you chance to clearly define parent Job for all of your coroutines.我会推荐选项 2。它会让你有机会为你的所有协程明确定义父Job That gives a chance to shut down the whole execution correctly too.这也提供了正确关闭整个执行的机会。

There are several more coroutine context keys to include - CoroutineName , CoroutineExceptionHandler and so one.还有几个协程上下文键要包括 - CoroutineNameCoroutineExceptionHandler等等。

Lastly, the structural concurrency may work better if you pass the CoroutineScope and the associated Job explicitly.最后,如果您显式传递CoroutineScope和关联的 Job,结构并发可能会更好地工作。
https://medium.com/@elizarov/structured-concurrency-722d765aa952 https://medium.com/@elizarov/structured-concurrency-722d765aa952

Also, take a look the explanation on that form Roman: https://medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055另外,看看罗马表格的解释: https : //medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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