7.1 Створення задач
Клас Task
в модулі asyncio використовується для управління виконанням
корутин. Задачі (Tasks)
являють собою обгортки для корутин,
що дозволяють управляти їх виконанням і відстежувати їх стан.
Клас Task
дозволяє запускати корутини паралельно, керуючи ними
через цикл подій.
Основні методи класу Task
Клас Task
— це певна обгортка над корутиною, яка дає
такі додаткові можливості:
Управління виконанням корутин:
Задачі дозволяють легко керувати виконанням корутин, контролювати їх стан і отримувати результати.
Скасування задач:
Можливість скасування задач робить Task
корисним для управління
тривалими операціями, які можуть вимагати зупинки до
завершення.
Зворотні виклики:
Задачі підтримують додавання зворотних викликів, що дозволяє виконувати додаткові дії при завершенні задач.
Створення задач:
Задачі створюються за допомогою функції
asyncio.create_task(coroutine)
або методу
loop.create_task(coroutine)
, які планують
виконання корутини.
import asyncio
async def say_hello():
print("Hello")
await asyncio.sleep(1)
print("World")
async def main():
task = asyncio.create_task(say_hello())
await task
asyncio.run(main())
7.2 Основні методи
Метод Task.cancel()
:
Запитує скасування задачі. Якщо задача ще не завершена, вона буде
завершена з викликом виключення CancelledError
.
Давайте напишемо невелику програму, яка дозволить нам це продемонструвати.
Створимо асинхронну задачу, яка буде просто чекати 10 секунд
Загорнемо її в об'єкт
Task
Почекаємо секунду, щоб задача (Task) почала виконуватися
Скасуємо задачу –
task.cancel()
-
Якщо далі спробувати почекати завершення задачі (Task) за допомогою оператора
await
, то ми отримаємо виключенняCancelledError
.
import asyncio
async def main():
task = asyncio.create_task(asyncio.sleep(10))
await asyncio.sleep(1)
task.cancel()
try:
await task
except asyncio.CancelledError:
print("Task was cancelled")
asyncio.run(main())
Метод Task.result()
:
Повертає результат виконання задачі. Якщо задача завершилася з
виключенням, воно буде викликано при виклику result()
.
import asyncio
async def main():
task = asyncio.create_task(asyncio.sleep(1, result='Completed'))
result = await task
print(result) # Output: Completed
asyncio.run(main())
У нашому випадку навіть не довелося писати додатковий код — оператор
await
розуміє, як працювати з об'єктом Task
: після виконання задачі
він сам викличе у нього метод result()
і поверне отриманий результат.
Метод Task.exception()
:
Повертає виключення, викликане задачею. Якщо задача завершилася
без виключення, повертає None
.
import asyncio
async def main():
task = asyncio.create_task(asyncio.sleep(1))
try:
result = await task
except Exception as e:
print(f"Task failed with exception: {e}")
asyncio.run(main())
Також додатковий код писати не потрібно — якщо в задачі виникло
виключення, метод exception()
буде викликаний оператором await
.
Метод Task.add_done_callback(callback)
:
Додає зворотний виклик (callback)
, який буде викликаний при
завершенні задачі.
import asyncio
def callback(future):
print("Task completed")
async def main():
task = asyncio.create_task(asyncio.sleep(1))
task.add_done_callback(callback)
await task
asyncio.run(main())
До задачі можна додати функцію, яка буде автоматично викликана, коли задача завершить виконання. Такий підхід дозволяє робити код дуже гнучким. Більш того, функцій можна додати кілька, і додавати їх можна до будь-яких задач.
Метод Task.done()
:
Повертає True
, якщо задача завершена (успішно, з помилкою або була
скасована).
import asyncio
async def main():
task = asyncio.create_task(asyncio.sleep(1))
await asyncio.sleep(1.5)
print(task.done()) # Output: True
asyncio.run(main())
За допомогою методу done()
можна дізнатися, чи успішно виконалася задача.
Вірніше, виконалася вона чи була скасована, адже якщо
виникло виключення, то формально задача може бути і не виконана,
але і скасована вона не була. Загалом, якщо задачу скасували (cancel)
,
то метод поверне False
, інакше поверне True
.