在挂起的函数中调用协程构建器(启动、异步)时,coroutineContext 不明确
Ambiguous coroutineContext while calling co-routine builders (launch, async) in a suspended function
我有一个 class Runner
实现了 CoroutineScope
接口,如下所示。它有一个名为 run
的挂起函数。当我在这个暂停的 run
函数中使用协同例程构建器函数 (launch
, async
) 时,我收到以下警告
Ambiguous coroutineContext due to CoroutineScope receiver of suspend
function
Runner
class 实现了一个 coroutineContext 属性。有人可以解释警告消息背后的逻辑吗?
class Runner: CoroutineScope {
override private val coroutineContext = Dispatchers.IO
suspend fun run() {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
}
尽量避免在 Coroutine Scoped class 或函数内挂起函数
除非它会抛出上述警告
class Runner: CoroutineScope {
override private val coroutineContext = Dispatchers.IO
suspend fun run() {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
}
至
class Runner: CoroutineScope {
//also remove the `private` visibility modifier
override val coroutineContext = Dispatchers.IO
fun run() {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
this.launch{
listOf(job1, job2).forEach { it.join() }
}
}
}
由于 suspend 修饰符,它是模棱两可的。您的 run()
函数将从另一个 couroutineScope 调用。所以它里面的 launch
构建器可以启动协程或在现有协程内挂起。这就是歧义。您可以通过删除挂起修饰符来修复它:
class Runner : CoroutineScope {
override val coroutineContext = Dispatchers.IO
fun run() = launch {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
}
您需要明确声明run()
使用 Runner 的 coroutineContext,这将消除歧义
suspend fun run() = withContext(coroutineContext) {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
或者,如果您添加一个参数,您可以使用调用 运行 的上下文,例如
suspend fun run(cc:CoroutineContext = coroutineContext) = withContext(cc) {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
我有一个 class Runner
实现了 CoroutineScope
接口,如下所示。它有一个名为 run
的挂起函数。当我在这个暂停的 run
函数中使用协同例程构建器函数 (launch
, async
) 时,我收到以下警告
Ambiguous coroutineContext due to CoroutineScope receiver of suspend function
Runner
class 实现了一个 coroutineContext 属性。有人可以解释警告消息背后的逻辑吗?
class Runner: CoroutineScope {
override private val coroutineContext = Dispatchers.IO
suspend fun run() {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
}
尽量避免在 Coroutine Scoped class 或函数内挂起函数 除非它会抛出上述警告
class Runner: CoroutineScope {
override private val coroutineContext = Dispatchers.IO
suspend fun run() {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
}
至
class Runner: CoroutineScope {
//also remove the `private` visibility modifier
override val coroutineContext = Dispatchers.IO
fun run() {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
this.launch{
listOf(job1, job2).forEach { it.join() }
}
}
}
由于 suspend 修饰符,它是模棱两可的。您的 run()
函数将从另一个 couroutineScope 调用。所以它里面的 launch
构建器可以启动协程或在现有协程内挂起。这就是歧义。您可以通过删除挂起修饰符来修复它:
class Runner : CoroutineScope {
override val coroutineContext = Dispatchers.IO
fun run() = launch {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
}
您需要明确声明run()
使用 Runner 的 coroutineContext,这将消除歧义
suspend fun run() = withContext(coroutineContext) {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}
或者,如果您添加一个参数,您可以使用调用 运行 的上下文,例如
suspend fun run(cc:CoroutineContext = coroutineContext) = withContext(cc) {
val job1 = launch { delay(2000); println("launching job1") }
val job2 = launch { delay(2000); println("launching job2") }
listOf(job1, job2).forEach { it.join() }
}