7.1 Creación de tareas
La clase Task
en el módulo asyncio se usa para gestionar la ejecución de corutinas. Las tareas (Tasks)
son envoltorios para corutinas, permitiendo gestionar su ejecución y monitorizar su estado. La clase Task
te permite ejecutar corutinas en paralelo, controlándolas a través del ciclo de eventos.
Principales métodos de la clase Task
La clase Task
es un tipo de envoltorio sobre la corutina, que da estas capacidades adicionales:
Gestión de la ejecución de corutinas:
Las tareas permiten gestionarlas fácilmente, controlar su estado y obtener sus resultados.
Cancelar tareas:
La posibilidad de cancelar tareas hace que Task
sea útil para manejar operaciones largas que pueden necesitar detenerse antes de completarse.
Callbacks:
Las tareas soportan la adición de callbacks, lo que permite realizar acciones adicionales al completar las tareas.
Creación de tareas:
Las tareas se crean usando la función asyncio.create_task(coroutine)
o el método loop.create_task(coroutine)
, que planean la ejecución de la corutina.
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 Métodos principales
Método Task.cancel()
:
Solicita la cancelación de la tarea. Si la tarea aún no ha terminado, se completará lanzando la excepción CancelledError
.
Vamos a escribir un pequeño programa para demostrarlo.
Vamos a crear una tarea asíncrona que simplemente esperará 10 segundos
La envolveremos en un objeto
Task
Esperaremos un segundo para que la tarea (Task) comience a ejecutarse
Cancelaremos la tarea –
task.cancel()
-
Si intentamos esperar la finalización de la tarea (Task) con el operador
await
, obtendremos la excepciónCancelledError
.
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())
Método Task.result()
:
Devuelve el resultado de la ejecución de la tarea. Si la tarea terminó con una excepción, se lanzará al llamar 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())
En nuestro caso, ni siquiera tuvimos que escribir código adicional: el operador await
entiende cómo trabajar con un objeto Task
: después de que la tarea se complete, llamará automáticamente el método result()
y devolverá el resultado obtenido.
Método Task.exception()
:
Devuelve la excepción generada por la tarea. Si la tarea terminó sin excepción, devuelve 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())
Tampoco es necesario escribir código adicional: si se produce una excepción en la tarea, el método exception()
será llamado por el operador await
.
Método Task.add_done_callback(callback)
:
Añade un callback (callback)
, que se llamará cuando la tarea se complete.
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())
Puedes añadir una función a la tarea que será llamada automáticamente cuando la tarea complete su ejecución. Este enfoque hace que el código sea muy flexible. Además, puedes añadir múltiples funciones, y estas se pueden añadir a cualquier tarea.
Método Task.done()
:
Devuelve True
si la tarea está completada (ya sea con éxito, con error o fue cancelada).
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())
Con el método done()
puedes saber si la tarea se completó con éxito. O más bien, si completó o fue cancelada, ya que si ocurrió una excepción, formalmente la tarea puede no haber sido completada, pero no fue cancelada tampoco. En resumen, si la tarea fue cancelada (cancel)
, el método devolverá False
, de lo contrario devolverá True
.
GO TO FULL VERSION