← Назад ко всем вопросам

Как отменить задачу в asyncio?

1️⃣ Как кратко ответить

"В asyncio для отмены задачи используется метод cancel(). Этот метод посылает задаче сигнал отмены, который она может обработать, выбросив исключение asyncio.CancelledError. Задача должна быть запущена, чтобы её можно было отменить."

2️⃣ Подробное объяснение темы

В Python, библиотека asyncio предоставляет инструменты для написания асинхронного кода, который может выполнять несколько операций одновременно, не блокируя основной поток выполнения. Одной из таких операций является отмена задачи.

Зачем отменять задачу?

Иногда в асинхронных приложениях возникает необходимость остановить выполнение задачи до её завершения. Это может быть полезно в следующих случаях:

  • Тайм-ауты: Если задача выполняется слишком долго, её можно отменить, чтобы освободить ресурсы.
  • Пользовательский ввод: Если пользователь отменяет операцию, например, загрузку файла, соответствующую задачу можно остановить.
  • Ошибки: Если возникает ошибка, которая делает дальнейшее выполнение задачи бессмысленным, её можно отменить.

Как работает отмена задачи?

В asyncio задача представляется объектом Task, который является обёрткой над корутиной. Чтобы отменить задачу, используется метод cancel(). Этот метод посылает задаче сигнал отмены, который она может обработать, выбросив исключение asyncio.CancelledError.

Пример отмены задачи

Рассмотрим простой пример, чтобы понять, как это работает:

import asyncio
​
async def my_coroutine():
    print("Task started")
    try:
        await asyncio.sleep(10)
    except asyncio.CancelledError:
        print("Task was cancelled")
        raise
    print("Task finished")
​
async def main():
    # Создаем задачу
    task = asyncio.create_task(my_coroutine())
​
    # Ждем немного времени, прежде чем отменить задачу
    await asyncio.sleep(1)
​
    # Отменяем задачу
    task.cancel()
​
    try:
        # Ждем завершения задачи
        await task
    except asyncio.CancelledError:
        print("Main: Task was cancelled")
​
# Запускаем главный цикл
asyncio.run(main())

Объяснение примера

  1. Создание задачи: Мы создаём задачу my_coroutine() с помощью asyncio.create_task().
  2. Отмена задачи: После ожидания в течение 1 секунды мы вызываем task.cancel(), чтобы отменить задачу.
  3. Обработка отмены: Внутри корутины my_coroutine() мы обрабатываем исключение asyncio.CancelledError, чтобы выполнить необходимые действия при отмене.
  4. Завершение задачи: Мы используем await task, чтобы дождаться завершения задачи и обработать возможное исключение CancelledError в main().

Тема: Асинхронность
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки