Проблема в том, что getter
даже не не запускает , что можно подтвердить, добавив печать в начале. Поскольку блок try
никогда не вводился, except
также не запускался.
Это происходит потому, что, в отличие от await
, ensure_future
не запускает выполнение сопрограммы сразу, а просто планирует ее запуск на следующей итерации цикла событий, как call_soon
для обычных функций. Поскольку вы немедленно отменяете задачу, она удаляется из набора, который можно запустить, и ее сопрограмма закрывается, даже не начавшись.
Добавьте await asyncio.sleep(0)
перед task.cancel()
, и вы должны наблюдать за ожидаемым поведением. Я подозреваю, что вам не нужно вносить такие изменения в ваш реальный код - в маловероятном случае, если задача будет отменена до ее запуска, как в примере, у нее не будет возможности получить ресурсы, которые пытаются / кроме очищает на первом месте.
Два тангенциальных замечания:
Вы, вероятно, захотите повторно повысить asyncio.CancelledError
после обработки, иначе это будет подавлено. Это не проблема в getter
, как показано в вопросе, но это может быть проблемой, если код был похоронен в вызове функции. Еще лучше рассмотреть возможность использования finally
или with
, которые распространяют исключение и обеспечивают освобождение ресурсов независимо от типа исключения.
Когда вам нужно создать задачу и запустить сопрограмму, loop.create_task
- это , предпочтительнее - asyncio.ensure_future
. Короче говоря, хотя оба делают одно и то же для сопрограмм, create_task
проясняет намерение; ensure_future
предназначен для приема более широкого спектра объектов и обеспечения будущего неопределенного типа.