目前,我正在尝试通过提高不同Dispatcher和上下文的使用来优化应用性能。我偶然发现的一个问题是,如果我在带有IO Dispatcher的协程中启动一个suspend函数,其他函数是否也会在同一个Dispatcher中执行?
示例
fun doSomething() {
viewModelScope.launch(Dispatchers.IO) {
getUserData(viewModelScope)
}
}
fun getUserData(innerScope: CoroutineScope) {
workerList.startUserDataWorker()
observeUserData(innerScope) // suspend function, is this called inside the IO Dipatcher?
}
// Will this be called inside the IO Dispatcher?
private suspend fun observeUserData(innerScope: CoroutineScope) {
observerWorkerStateAndPassData(workerList.userDataWorkInfo, USER_DATA_OUTPUT_OPTION).collect { status ->
when(status) {
is Status.Loading -> {
_userDataState.postValue(Status.loading())
}
is Status.Success -> {
// Will getShippingAddressList() also be called on the IO Dispatcher?
_userDataState.postValue(Status.success(getShippingAddressList()))
}
is Status.Failure -> {
_userDataState.postValue(Status.failed(status.message.toString()))
}
}
}
}
// Getting Address from the local room cache. Is this called on the IO Dispatcher?
private suspend fun getShippingAddressList(): List<UserDeliveryAddress> {
val uncachedList = userAddressDao.getAllAddress(UserAddressCacheOrder.SHIPPING)
return userAddressCacheMapper.mapFromEntityList(uncachedList)
}
1条答案
按热度按时间juzqafwq1#
除了下面的例外,你使用的调度器在调用一个suspend函数时是无关紧要的。它只在调用blocking函数时是相关的。挂起不使用调度器线程。
例外情况:
withContext(Dispatchers.Main)
Package 函数内容,从而将main-only限制从view类传递到suspend函数调用者。既然你可以使用withContext
来避免潜在的问题,至少当suspend函数是公共的时候,你也可以使用Dispatchers.Main.immediate
来避免不必要的线程切换。withContext(mySingleThreadDispatcher)
Package 关注对象的这些使用,这样哪个调度程序正在调用就仍然无关紧要暂停功能。在你的例子中,哪个调度器调用
observeUserData
并不重要,因为这个函数在它收集的时候会无限期地挂起,而且当它收集的时候,它只调用非阻塞的线程安全函数LiveData.postValue()
。