Как ведет себя asyncio.create_task и Task.done()

Как ведет себя asyncio.create_task и Task.done()

@python_quiz

Разберем этот квиз

Условие — небольшой фрагмент кода на asyncio:

python

Код простой, но проверяет важные детали: что возвращает create_task, когда задача считается завершённой и что происходит при вызове result().

Что происходит в коде — пошагово

  • asyncio.create_task создаёт объект Task и планирует его выполнение в событийном цикле. В момент создания задача ещё не выполнена — она запланирована.
  • task.done() возвращает True только если задача полностью завершена (выполнена, отменена или завершилась с ошибкой).
  • asyncio.sleep(0.1, result=42) будет завершена через ~0.1 секунды и вернёт 42.
  • В коде сразу после create_task вызывается print(task.done()) — это происходит до того, как цикл успеет выполнить задачу, поэтому ожидаемо значение будет False.
  • Затем main делает await asyncio.sleep(0.2) — это даёт циклу время (больше 0.1) выполнить запущенную таску. После этого task уже завершена, и task.result() безопасно вернёт 42.

Ожидаемый вывод программы

text

Первой строкой False (задача ещё не выполнена), затем True и 42 (задача выполнена и вернула значение).

Разбор предложенных вариантов ответов

Ниже — анализ каждого варианта и почему он верен или неверен в контексте приведённого кода.

  • "Сначала False, потом False и ошибка при result()"

- Неверно. После await asyncio.sleep(0.2) задача должна успеть завершиться (0.2 > 0.1). Поэтому done() не останется False, и result() не вызовет ошибку.

  • "Сначала False, потом True 42"

- Соответствует описанному поведению. Сразу после create_task задача ещё не выполнена → False. После ожидания 0.2 секунды задача завершится и вернёт 42.

  • "Сначала True, потом True 42"

- Неверно. Невозможно, чтобы task.done() было True сразу после create_task: задача только что запланирована и ещё не выполнена в тот же момент печати.

  • "Сначала True, потом False и ошибка при result()"

- Неверно и логически противоречиво: задача не может стать "выполненной" (True) и затем снова "невыполненной" (False); кроме того, если done() True, вызов result() не вызовет ошибку (если задача не завершилась исключением).

Дополнительные замечания и альтернативы

  • Если вместо await asyncio.sleep(0.2) в main вы ничего не делаете (или ждёте меньше 0.1 секунды), то задача может ещё не успеть завершиться и попытка вызвать task.result() приведёт к исключению InvalidStateError.
  • Другой вариант корректного ожидания результата — явно await task. Тогда вы гарантированно получите результат:

`python
await task
print(task.done(), task.result()) # True 42
`

  • create_task планирует выполнение одновременно с исполнением текущей сопрограммы — это ключ к параллелизму в asyncio.

Вывод

create_task возвращает незавершённый Task (done() = False). Если дать событийному циклу достаточно времени (или явно await task), задача завершится, done() станет True, и result() вернёт ожидаемое значение (в этом примере 42).

Report Page