在CoroutineScope中选择调度程序

huangapple go评论57阅读模式
英文:

Selecting Dispatchers in CoroutineScope

问题

以下是翻译好的代码部分:

private fun exampleFunc() {
    CoroutineScope(Dispatchers.??).launch {
        exampleFunc1()
        exampleFunc2()
    }
}

private suspend fun exampleFunc1(): Int = withContext(Dispatchers.Main) {
    // 长代码
    return@withContext 0
}

private suspend fun exampleFunc2(): Int = withContext(Dispatchers.IO) {
    // 长代码
    return@withContext 0
}

请注意,代码中的 "Dispatchers.??" 部分是需要您选择适当的调度器,具体选择取决于您的应用程序需求和性能优化。这里无法提供具体的建议,因为需要根据您的应用程序上下文来选择合适的 Dispatcher。

英文:

Having this example code:

private fun exampleFunc() {
    CoroutineScope(Dispatchers.??).launch {
        exampleFunc1()
        exampleFunc2()
    }
}

private suspend fun exampleFunc1(): Int = withContext(Dispatchers.Main)  {
    //Long code
    return@withContext 0
}

private suspend fun exampleFunc2(): Int = withContext(Dispatchers.IO)  {
    //Long code
    return@withContext 0
}

exampleFunc1 will run on Main and exampleFunc2 will run on IO. But CoroutineScope requres me to choose a Dispatcher, and there is no option to leave it empty like in GlobalScope.launch. What is your recommendation in this case?

答案1

得分: 1

你不应该创建单独的CoroutineScope来启动单个协程。这就是GlobalScope的作用,但应该避免使用它,因为通常你关心的是何时结束其生命周期以释放/取消。

我不确定为什么CoroutineScope()函数不允许你将其留空以便使用EmptyCoroutineContext(从而使用Dispatchers.Default)。但也许他们认为你至少会希望为其上下文提供一个CoroutineName以用于日志记录和异常消息的目的。

如果挂起函数不能在任意调度程序上运行,它们应该始终在内部使用withContext,因此最终调用代码中使用的调度程序并不重要。在你的示例代码中,协程只调用挂起函数,所以无论你选择哪个调度程序,行为都不会有区别。

如果你在此范围内调用的根协程会触及只能在主线程上处理的内容,那么在CoroutineScope中使用Dispatchers.Main作为默认上下文是有道理的。

英文:

You shouldn't be creating one-off CoroutineScopes to launch a single coroutine anyway. That's what GlobalScope is for, and it should be avoided because you normally care about when something is going out of its lifecycle of usefulness and should therefore be released/cancelled.

I don't know for sure why the CoroutineScope() function doesn't allow you to leave it blank so it will use EmptyCoroutineContext (and therefore Dispatchers.Default). But maybe they figured you would at minimum want to be giving its context a CoroutineName for logging and exception message purposes.

Suspend functions should always internally use withContext if they cannot accept being run on any arbitrary dispatcher, so ultimately it won't matter what dispatcher is being used in the calling code. In your example code, the coroutine is only calling suspend functions, so there will be no difference in behavior, no matter which dispatcher you choose.

If the root coroutines that you call in this scope are touching things that can only be touched on the main thread, then in makes sense to use Dispatchers.Main as your default context in the CoroutineScope.

huangapple
  • 本文由 发表于 2023年6月30日 02:10:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76583625.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定