我有以下类(class):
class Repository(
private val assetManager: AssetManager,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) {
suspend fun fetchHeritagesList(): HeritageResponse = withContext(ioDispatcher) {
try {
// TODO Blocking method call?
val bufferReader = assetManager.open("heritages.json").bufferedReader()
...
我想知道为什么我会在
open("heritages.json")
中收到警告说Innapropriate blocking method call
吗? withContext(ioDispatcher)
不能解决这个问题吗?感谢您的解释!
最佳答案
IntelliJ检查在可挂函数内部阻止调用,其功能不足以查看Dispatchers.IO
及其在withContext
中的使用之间的间接级别。这是此问题的最小复制者:
class IoTest {
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
suspend fun indirectRef() = withContext(ioDispatcher) {
Thread.sleep(1) // Flagged as inappropriate blocking call
}
suspend fun directRef() = withContext(Dispatchers.IO) {
Thread.sleep(1) // Not flagged
}
}
但是,与我的情况不同,您的
ioDispatcher
是通过构造函数公开供注入(inject)的,因此您可以轻松地提供Dispatchers.Main
而不是它,这将构成不适当的阻塞。不幸的是,我还没有听说过将分派(dispatch)器的契约(Contract)正式指定为“容许阻塞调用”的任何方式,因此您可以在构造函数中强制执行它。
YouTrack上已经存在类似的问题。