중지 컨텍스트 내에서 잠재적으로 문제가 될 수 있는 묵시적 CoroutineScope 리시버의 액세스를 보고합니다.
When a suspend function or lambda captures an implicit CoroutineScope receiver from the outer context, it might lead to
unexpected behavior.
Such code can be prone to violating the rules of Structured Concurrency, even though it might look deceptively well-structured.
This can lead to incorrect behaviors when handling errors, cancelling computations, or managing lifetimes.
A typical example:
fun processFlow(flow: Flow<String>) {
runBlocking {
flow.collectLatest {
// launched on this@runBlocking CoroutineScope
launch {
longProcessing(value)
}
}
}
}
suspend fun longProcessing(value: String) { ... }
In the example above, the launch { ... } call launches coroutines in the implicit
CoroutineScope from the outer runBlocking call.
Because of this, collectLatest would not be able
to cancel those coroutines when it needs to.
This inspection will detect that launch is called on a
CoroutineScope which is captured from the outside of the current
suspending lambda (i.e. collectLatest's body).
For more information about this particular problem, see this GitHub Issue.
Possible solutions:
이 문제를 해결하는 방법은 다음과 같습니다.
coroutineScope { ... } builder to create a child scope that is tied to the suspend function's lifecycleCoroutineScope comes from the current syntactical context
In case you are sure that the code is correct, you can explicitly specify the receiver
to make your intention clear. In the example above, that would be this@runBlocking.launch { ... }.
Note, however, that in this case the semantics of the code won't change.