何时在Kotlin中启动新范围

何时在Kotlin中启动新范围,kotlin,coroutine,Kotlin,Coroutine,我的代码中有一个阻塞rest调用,我希望在不同于GlobalScope调用的上下文中运行它(这是最好的实践),但我不知道是否还需要为该操作创建一个新的作用域 一方面,据说它在不同于全局的范围内运行,因此,实际上,范围和上下文几乎是相同的 我正在SpringWebFlux(netty)应用程序中运行并使用rest调用。 考虑下面的代码示例: 这一条似乎是“最佳实践”(这篇博文特别指出不要使用CoroutineScope(Dispatchers.IO)。启动 val blockingScop

我的代码中有一个阻塞rest调用,我希望在不同于GlobalScope调用的上下文中运行它(这是最好的实践),但我不知道是否还需要为该操作创建一个新的作用域

一方面,据说它在不同于全局的范围内运行,因此,实际上,范围和上下文几乎是相同的

我正在SpringWebFlux(netty)应用程序中运行并使用rest调用。 考虑下面的代码示例:

这一条似乎是“最佳实践”(这篇博文特别指出不要使用
CoroutineScope(Dispatchers.IO)。启动

    val blockingScope = CoroutineScope(Dispatchers.IO)
    suspend fun one() = withContext(blockingScope.coroutineContext) {
        val queryParams = arrayOf(
             BasicNameValuePair("name", "key"),
        )
        blockingClient.get("...", JsonNode::class.java, queryParams)
    }
还有,我是否需要处理这里的
blockingScope.cancel()

但是,是什么阻止我仍然使用它(或者它将如何影响应用程序)

是什么阻止我继续使用它(或者它会产生什么影响 (申请表)

您发布的两个代码片段在功能上应该几乎相同。在第一个代码片段中,您使用
Dispatchers.IO
作为上下文创建一个作用域,然后使用刚刚传递到新创建的作用域的
CoroutineContext
调用
withContext
生成器函数。在第二个代码片段中,您直接传过去

但是,请注意,如果您使用在第一个代码段中创建的
CoroutineScope
启动其他协同路由,则取消或失败您作用域的任何子协同路由将导致取消所有其他子协同路由(请参阅)

还有,我是否需要处理这里的
blockingScope.cancel()

如果你的意思是处理
阻塞scope.cancel()
你的意思是需要在你的作用域上调用
.cancel()
,那么不,你不需要。你在
协同作用域上调用这个函数来取消它的所有子协同作用域。所以除非你想这样做,否则你不应该调用这个函数:)

备注

正如在对你的问题的评论中指出的,关于

CoroutineScope(coroutineContext)。启动{…}


这是因为您正在访问当前的
coroutineContext
以启动另一个coroutine-因此,根据当前的上下文,新的coroutine可以在一个或另一个上下文中启动-您不会仅仅通过查看函数代码就知道。

它说在哪里不使用
CoroutineScope(Dispatchers.IO)。启动{}
?在博文中寻找“不要这样做!这会使启动协同程序的范围变得不透明和隐式”,他说不要执行
CoroutineScope(coroutineContext)。启动{}
。我看错了吗?这是因为你从其他事物中获得了上下文。
    suspend fun one() = withContext(Dispatchers.IO) {
        val queryParams = arrayOf(
             BasicNameValuePair("name", "key"),
        )
        blockingClient.get("...", JsonNode::class.java, queryParams)
    }