我有以下类(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上已经存在类似的问题。

10-07 17:05