中断コンテキスト内からの潜在的に問題のある暗黙の CoroutineScope レシーバーアクセスを報告します。
中断関数かラムダが外側のコンテキストから暗黙の CoroutineScope レシーバーをキャプチャしていると、予期しない動作が発生する可能性があります。
そのようなコードは見た目はよく構造化されているように見えても、構造化並行性の規則に違反しがちです。
これにより、エラーの処理、処理のキャンセル、ライフタイムの管理時に不正な動作が発生する可能性があります。
典型的な例:
fun processFlow(flow: Flow<String>) {
runBlocking {
flow.collectLatest {
// this@runBlocking CoroutineScope で開始されます
launch {
longProcessing(value)
}
}
}
}
suspend fun longProcessing(value: String) { ... }
上記の例では、launch { ... } の呼び出しが外側の runBlocking 呼び出しから暗黙の CoroutineScope でコルーチンを開始しています。
このため、collectLatest はこのようなコルーチンを必要に応じてキャンセルできなくなります。
このインスペクションは、launch が現在のサスペンドラムダ (つまり collectLatest の本体) の外からキャプチャされている CoroutineScope に対して呼び出されていることを検出します。
この特定の問題に関する詳細については、この GitHub 課題 を参照してください。
可能な解決策:
この問題を解決するため、次の操作を実行できます:
coroutineScope { ... } ビルダーを使用し、suspend 関数のライフサイクルに関連付けられた子スコープを作成するCoroutineScope が現在の構文コンテキストから導出されるようにする
このコードが正しいと確信している場合は、レシーバーを明示的に指定して意図を明確にすることができます。 上記の例では、それは this@runBlocking.launch { ... } になるでしょう。
ただし、この場合はコードのセマンティクスは変わりません。