Pull to refresh

Comments 9

Глупый вопрос, но почему ключевое слово для короутин именно suspend? Оно ведь означает "приостановить". Почему бы не сделать что-нибудь более понятное, типа async, asynchronous, awaitable, coroutine ?

suspend не является ключевым словом для корутин. Им помечают функции, которые как раз-таки могут прерываться.

Отличная статья!

Было бы здорово увидеть более подробное описание того, как это вяжется с многопоточностью и планированием задач.

Ведь если я ничего не путаю, даже бесконечный цикл в suspend функции не вызывает зависания интерфейса если внутри самого цикла есть точка прерывания, это значит что в какой то момент вместо продолжения дробления данных в цикле state машины - она планирует эту задачу вероятно куда-то в handler.post на android и даёт тем самым прогрузить интерфейс, вот интересно узнать как эта часть работает. (или возможно dispatcher main потока каждую следующую итерацию планирует в post o.O)

Ну и вообще наверное по работе dispatcher - ов должно быть много интересного - там же получается наверное возможна ситуация, когда одна корутина в процессе выполнения переключилась на другой поток, а другая наоборот переключилась с другого на текущий, и планировщик должен запустить её и вот это все))

она планирует эту задачу вероятно куда-то в handler.post на android и даёт тем самым прогрузить интерфейс

Именно так.

Следите за руками: компилятор генерит имплементацию Continuation для каждой suspend функции. Эта имплементация наследуется от ContinuationImpl, где при вызове resumeWith() в текущем контексте ищется ContinuationInterceptor, у которого вызывается методinterceptContinuation().

Идём далее, стандартные диспетчеры реализуют СontinuationInterceptor, и в методе interceptContinuation()они превращают переданный Continuation в DispatchedContinuation. DispatchedContinuation нужен для 2 вещей: во-первых, сам по себе в конечном итоге наследуется от Runnable, во-вторых, в resumeWith() он ищет в контексте CoroutineDispatcher и вызывает у него метод dispatch(context: CoroutineContext, block: Runnable) с самим собой в качестве аргумента.

Дальше очень просто — в dispatch() переданные раннаблы раскидываются по экзекьюторам (ну, на самом деле не очень просто, всякие балансировки и оптимизации тоже присутствуют). Default и IO диспетчеры используют пулы потоков, а Main в Android использует Handler.

В рамках комментария, конечно, сложно нормально описать всю эту кухню, есть в планах сделать статью по этой теме, да всё никак руки не доходят.

Спасибо за ответ, примерно так себе это и представлял, но теперь можно быть уверенным))

Надеюсь когда нибудь у вас дойдут руки до статьи, было бы здорово)

Спасибо, в оригинальной статье этот момент не описывается и мне тоже "нехватило" этой инфы. Постараюсь найти по этой теме, что-нибудь в ближайшее время.

Хорошая статья. Хотелось бы добавить, что диспатчер может также закинуть исполнение корутины в другом потоке еще до того, как случился resume после COROUTINE_SUSPEND, что позволяет не блокировать текущий поток, если первые операции блокирующие.

Sign up to leave a comment.

Articles