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 segundosLa envolveremos en un objetoTaskEsperaremos un segundo para que la tarea (Task) comience a ejecutarseCancelaremos la tarea –task.cancel()-
Si intentamos esperar la finalización de la tarea (Task) con el operadorawait, 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