Коварный AttachExternalCancellatio

Если вы работаете с асинхронностью в Unity, то наверняка знакомы с UniTask. Это более эффективный и удобный для Unity инструмент, чем обычные шарповые Task. Github

Его удобство часто достигается за счёт разнообразного “сахара”, с которым важно не переборщить. Одна из таких “сладостей” — это метод AttachExternalCancellation, который очень часто используют не по назначению.

🔰 В чём проблема

Обычно для прерывания асинхронной операции используют CancellationToken: его передают внутрь и отслеживают.

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

🖇️ Подробнее про это и полезные советы можно почитать здесь.

Соответственно, если это какой-то метод UniTask, например Delay, то вся логика остановки внутри уже реализована — достаточно только передать токен.

Почему-то принято считать, что AttachExternalCancellation работает таким же образом, хотя его можно приставить к любому асинхронному методу, который даже изначально и не подразумевал передачу ему токена.

UniTask и Task — это не сопрограммы, которые привязаны к циклу конкретного MonoBehaviour. Соответственно, они не смогут остановиться магическим образом, если к ним просто “сбоку” приставить токен.

❗️ AttachExternalCancellation не останавливает выполнение кода внутри задачи. Он лишь останавливает ожидание этой задачи.

Т.е. если вы делали await какого-то метода — он прекратится, но сам асинхронный метод продолжит работать.

Похожим образом работает и метод ToUniTask(CancellationToken token). Ему тоже не стоит доверять.

Продолжение — в Telegram 🗯️

Коварный AttachExternalCancellatio | Сетка — социальная сеть от hh.ru