Asyncio.create task: примеры (PYTHON)
asyncio.create_task(coro: coroutine): asyncio.TaskБазовое описание функции asyncio.create_task
Функция asyncio.create_task() представляет инструмент для запуска корутин в качестве асинхронных задач внутри цикла событий. Использование этой функции позволяет выполнять несколько корутин конкурентно, не дожидаясь завершения каждой по отдельности.
Применение функции наблюдается в ситуациях, когда требуется параллельное выполнение нескольких асинхронных операций, например, одновременные сетевые запросы, обработка файлов или взаимодействие с периферийными устройствами.
Аргументы функции
coro: обязательный аргумент, представляющий корутину для выполнения.name: необязательный аргумент строкового типа для присвоения имени задаче. Появился в Python 3.8.context: необязательный аргумент, позволяющий передавать контекст выполнения (например, дляcontextvars). Добавлен в Python 3.11.
Возвращаемое значение
Функция возвращает объект типа Task, который является подклассом Future. Этот объект позволяет управлять выполнением задачи, ожидать её завершения или отменять выполнение.
Примеры использования asyncio.create_task
Базовый пример создания и выполнения задачи:
import asyncio
async def example_coroutine():
await asyncio.sleep(1)
return "Результат"
async def main():
task = asyncio.create_task(example_coroutine())
result = await task
print(result)
asyncio.run(main())Результат
Пример с именем задачи:
async def main():
task = asyncio.create_task(
example_coroutine(),
name="MyTask"
)
print(f"Имя задачи: {task.get_name()}")
await task
asyncio.run(main())Имя задачи: MyTask
Альтернативные функции в Python
asyncio.ensure_future(): функция создает задачу из различных объектов, включая корутины, Future и awaitable-объекты. Отличие от create_task заключается в более широкой области применения, но меньшей эффективности для корутин.asyncio.gather(): функция позволяет запустить несколько корутин параллельно и собрать их результаты. Использование предпочтительно при необходимости ожидания завершения группы задач.asyncio.wait(): функция обеспечивает ожидание завершения задач с возможностью установки условий завершения. Применение полезно при работе с динамическим набором задач.
Аналоги в других языках программирования
JavaScript: использование Promise и async/await с запуском через микрозадачи.
async function example() {
return "Done";
}
const task = example();
task.then(result => console.log(result));Done
Go: горутины запускаются с помощью ключевого слова go.
package main
import (
"fmt"
"time"
)
func example() {
fmt.Println("Выполнено")
}
func main() {
go example()
time.Sleep(time.Second)
}Выполнено
Kotlin: корутины запускаются через launch или async в области видимости.
import kotlinx.coroutines.*
fun main() = runBlocking {
val task = launch {
delay(1000)
println("Завершено")
}
task.join()
}Завершено
Типичные ошибки при использовании
Отсутствие ожидания выполнения задачи приводит к незавершению программы:
async def main():
asyncio.create_task(example_coroutine())
# Задача может не успеть выполниться
asyncio.run(main())Программа завершается без вывода
Попытка создания задачи вне цикла событий вызывает ошибку:
task = asyncio.create_task(example_coroutine()) # Ошибка!RuntimeError: no running event loop
Изменения в последних версиях Python
- Python 3.8: добавлен параметр
nameдля именования задач. - Python 3.11: введен параметр
contextдля управления контекстом выполнения. Добавлена возможность отмены задач по группам черезasyncio.TaskGroup. - Python 3.12: улучшена производительность и отладка задач.
Расширенные примеры применения
Создание нескольких задач с обработкой исключений:
async def risky_coroutine(id):
if id == 2:
raise ValueError(f"Ошибка в задаче {id}")
return f"Успех {id}"
async def main():
tasks = [
asyncio.create_task(risky_coroutine(i))
for i in range(4)
]
for task in tasks:
try:
result = await task
print(result)
except ValueError as e:
print(f"Поймано исключение: {e}")
asyncio.run(main())Успех 0 Успех 1 Поймано исключение: Ошибка в задаче 2 Успех 3
Использование контекста выполнения:
import contextvars
ctx_var = contextvars.ContextVar('var', default='default')
async def context_aware():
print(f"Значение: {ctx_var.get()}")
async def main():
ctx_var.set('основной')
task_ctx = contextvars.copy_context()
ctx_var.set('измененный')
task = asyncio.create_task(
context_aware(),
context=task_ctx
)
await task
asyncio.run(main())Значение: основной