Код: Выделить всё
class dispatch : ExecutorCoroutineDispatcher() {
private val services = Executors.newCachedThreadPool()
override val executor: Executor
get() = services
override fun dispatch(context: CoroutineContext, block: Runnable) {
println("dispatch ")
if(this.isDispatchNeeded(context)){
executor.execute(block)
}else{
Dispatchers.Unconfined.dispatch(context , block)
}
}
override fun isDispatchNeeded(context: CoroutineContext): Boolean {
println("isDispatchedNeeded ")
// Implement your custom logic here to determine if dispatch is needed
return false // assuming yield() call in loop so return false
}
override fun close() {
services.shutdown()
}
}
fun main() {
runBlocking {
launch(dispatch()) {
for (i in 1..3) {
println("start")
yield()// dispatch() call in loop may cause stackOverFlowError
println("end")
}
}
launch(dispatch()) {
println("some suspend function")
work() // some suspend work
}
}
}
suspend fun work() {
delay(1000) // Simulating some suspend work
}
Этот метод должен гарантировать, что данный блок в конечном итоге будет вызван, иначе система может зайти в состояние тупика и никогда из него не выйти.
Этот метод должен гарантировать, что данный блок в конечном итоге будет вызван.
Этот метод должен гарантировать, что данный блок в конечном итоге будет вызван, иначе система может войти в состояние тупика и никогда не выйти из него.
Этот метод должен гарантировать, что данный блок в конечном итоге будет вызван.
Этот метод должен гарантировать, что данный блок в конечном итоге будет вызван, иначе система может войти в состояние тупика и никогда не выйти из него.
Этот метод должен гарантировать, что данный блок будет в конечном итоге вызван. p>
Этот метод не должен немедленно вызывать блок. Это может привести к возникновению ошибки StackOverflowError при повторном вызове диспетчеризации, например, когда в цикле вызывается выход. Чтобы выполнить блок на месте, необходимо вернуть false из isDispatchNeeded и в таких случаях делегировать реализацию отправки Dispatchers.Unconfined.dispatch. Для поддержки этого механизм сопрограмм обеспечивает выполнение на месте и формирует цикл событий, чтобы избежать несвязанной рекурсии.
---> в моем коде, когда в цикле есть метод yield(), затем isDispatchNeeded возвращает false, а при отправке используйте Unconfined Dispatcher, как указано выше в документации, чтобы избежать ошибки stackoverflow, но в документации, как я могу справиться, когда нам нужно немедленно вызвать блок[runnable], чтобы избежать взаимоблокировки.
пожалуйста, кто-нибудь Исправьте мой код, который правильно обрабатывает отправку сопрограмм, учитывая, вызывается ли диспетчерская() в цикле или нет, и должен обеспечить правильную обработку ошибок и управление исключениями в диспетчеризации() , isDispatchedNeeded() , что обрабатывать такие проблемы, как взаимоблокировка, StackOverflowError и т. д.?
Подробнее здесь: https://stackoverflow.com/questions/786 ... ementation
Мобильная версия