# Corrutinas y Tareas

Esta sección describe las API de asyncio de alto nivel para trabajar con corrutinas y tareas.

- Corrutinas

- Esperables

- Ejecutando un programa asyncio

- Creando Tareas

- Durmiendo

- Ejecutando Tareas Concurrentemente

- Protección contra Cancelación

- Tiempo agotado

- Esperando Primitivas

- Ejecutando en Hilos

- Planificación Desde Otros Hilos

- Introspección

- Objeto Task

- Corrutinas basadas en generadores

## Corrutinas

Source code: Lib/asyncio/coroutines.py

Coroutines declared with the async/await syntax is the preferred way of writing asyncio applications. For example, the following snippet of code prints «hello», waits 1 second, and then prints «world»:

    >>> import asyncio

    >>> async def main():
    ...     print('hello')
    ...     await asyncio.sleep(1)
    ...     print('world')

    >>> asyncio.run(main())
    hello
    world

Tenga en cuenta que simplemente llamando a una corrutina no programará para que se ejecute:

    >>> main()
    <coroutine object main at 0x1053bb7c8>

Para ejecutar realmente una corrutina, asyncio proporciona tres mecanismos principales:

- La función `asyncio.run()` para ejecutar la función de punto de entrada de nivel superior «main()» (consulte el ejemplo anterior.)

- Esperando en una corrutina. El siguiente fragmento de código imprimirá «hola» después de esperar 1 segundo y luego imprimirá «mundo» después de esperar otros 2 segundos:

      import asyncio
      import time

      async def say_after(delay, what):
          await asyncio.sleep(delay)
          print(what)

      async def main():
          print(f"started at {time.strftime('%X')}")

          await say_after(1, 'hello')
          await say_after(2, 'world')

          print(f"finished at {time.strftime('%X')}")

      asyncio.run(main())

  Salida esperada:

      started at 17:13:52
      hello
      world
      finished at 17:13:55

- La función `asyncio.create_task()` para ejecutar corrutinas concurrentemente como asyncio `Tasks`.

  Modifiquemos el ejemplo anterior y ejecutemos dos corrutinas `say_after` concurrentemente:

      async def main():
          task1 = asyncio.create_task(
              say_after(1, 'hello'))

          task2 = asyncio.create_task(
              say_after(2, 'world'))

          print(f"started at {time.strftime('%X')}")

          # Wait until both tasks are completed (should take
          # around 2 seconds.)
          await task1
          await task2

          print(f"finished at {time.strftime('%X')}")

  Tenga en cuenta que la salida esperada ahora muestra que el fragmento de código se ejecuta 1 segundo más rápido que antes:

      started at 17:14:32
      hello
      world
      finished at 17:14:34

## Esperables

Decimos que un objeto es un objeto esperable si se puede utilizar en una expresión `await`. Muchas API de asyncio están diseñadas para aceptar los valores esperables.

Hay tres tipos principales de objetos esperables: corrutinas, Tareas y Futures.

Corrutinas

Las corrutinas de Python son esperables y por lo tanto se pueden esperar de otras corrutinas:

    import asyncio

    async def nested():
        return 42

    async def main():
        # Nothing happens if we just call "nested()".
        # A coroutine object is created but not awaited,
        # so it *won't run at all*.
        nested()

        # Let's do it differently now and await it:
        print(await nested())  # will print "42".

    asyncio.run(main())

Importante

En esta documentación se puede utilizar el término «corrutina» para dos conceptos estrechamente relacionados:

- una función corrutina: una función `async def`;

- un objeto corrutina: un objeto retornado llamando a una función corrutina.

asyncio también es compatible con corrutinas heredadas generator-based.

Tareas

Las tareas se utilizan para programar corrutinas concurrentemente.

Cuando una corrutina se envuelve en una Tarea con funciones como `asyncio.create_task()` la corrutina se programa automáticamente para ejecutarse pronto:

    import asyncio

    async def nested():
        return 42

    async def main():
        # Schedule nested() to run soon concurrently
        # with "main()".
        task = asyncio.create_task(nested())

        # "task" can now be used to cancel "nested()", or
        # can simply be awaited to wait until it is complete:
        await task

    asyncio.run(main())

Futures

Un `Future` es un objeto esperable especial de bajo-nivel que representa un resultado eventual de una operación asíncrona.

Cuando un objeto Future es esperado significa que la corrutina esperará hasta que el Future se resuelva en algún otro lugar.

Los objetos Future de asyncio son necesarios para permitir que el código basado en retro llamada se use con async/await.

Normalmente , no es necesario crear objetos Future en el código de nivel de aplicación.

Los objetos Future, a veces expuestos por bibliotecas y algunas API de asyncio, pueden ser esperados:

    async def main():
        await function_that_returns_a_future_object()

        # this is also valid:
        await asyncio.gather(
            function_that_returns_a_future_object(),
            some_python_coroutine()
        )

Un buen ejemplo de una función de bajo nivel que retorna un objeto Future es `loop.run_in_executor()`.

## Ejecutando un programa asyncio

`asyncio.``run`(coro, *, debug=False)

  Ejecuta la coroutine coro y retornando el resultado.

  Esta función ejecuta la corrutina pasada, encargándose de administrar el bucle de eventos asyncio, finalizing asynchronous generators y cerrando el threadpool.

  Esta función no se puede llamar cuando otro bucle de eventos asyncio se está ejecutando en el mismo hilo.

  Si debug es `True`, el bucle de eventos se ejecutará en modo debug.

  Esta función siempre crea un nuevo ciclo de eventos y lo cierra al final. Debe usarse como un punto de entrada principal para los programas asyncio, e idealmente solo debe llamarse una vez.

  Ejemplo:

      async def main():
          await asyncio.sleep(1)
          print('hello')

      asyncio.run(main())

  Nuevo en la versión 3.7.

  Distinto en la versión 3.9: Actualizado para usar `loop.shutdown_default_executor()`.

  Nota

  El código fuente para `asyncio.run()` se puede encontrar en Lib/asyncio/runners.py.

## Creando Tareas

Source code: Lib/asyncio/tasks.py

`asyncio.``create_task`(coro, *, name=None)

  Envuelve una coroutine coro en una `Task` y programa su ejecución. Retorna el objeto Tarea.

  Si name no es `None`, se establece como el nombre de la tarea mediante `Task.set_name()`.

  La tarea se ejecuta en el bucle retornado por `get_running_loop()`, `RuntimeError` se genera si no hay ningún bucle en ejecución en el subproceso actual.

  Importante

  Save a reference to the result of this function, to avoid a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn’t referenced elsewhere may get garbage collected at any time, even before it’s done. For reliable «fire-and-forget» background tasks, gather them in a collection:

      background_tasks = set()

      for i in range(10):
          task = asyncio.create_task(some_coro(param=i))

          # Add task to the set. This creates a strong reference.
          background_tasks.add(task)

          # To prevent keeping references to finished tasks forever,
          # make each task remove its own reference from the set after
          # completion:
          task.add_done_callback(background_tasks.discard)

  Nuevo en la versión 3.7.

  Distinto en la versión 3.8: Added the name parameter.

## Durmiendo

coroutine `asyncio.``sleep`(delay, result=None)

  Bloquea por delay segundos.

  Si se proporciona result, se retorna al autor de la llamada cuando se completa la corrutina.

  `sleep()` siempre suspende la tarea actual, permitiendo que se ejecuten otras tareas.

  Establecer el retraso en 0 proporciona una ruta optimizada para permitir que se ejecuten otras tareas. Esto puede ser utilizado por funciones de ejecución prolongada para evitar bloquear el bucle de eventos durante toda la duración de la llamada a la función.

  Deprecated since version 3.8, removed in version 3.10: El parámetro `loop`. Esta función ha estado obteniendo implícitamente el ciclo en ejecución actual desde 3.7. Consulte What’s New in 3.10’s Removed section para obtener más información.

  Ejemplo de una rutina que muestra la fecha actual cada segundo durante 5 segundos:

      import asyncio
      import datetime

      async def display_date():
          loop = asyncio.get_running_loop()
          end_time = loop.time() + 5.0
          while True:
              print(datetime.datetime.now())
              if (loop.time() + 1.0) >= end_time:
                  break
              await asyncio.sleep(1)

      asyncio.run(display_date())

  Distinto en la versión 3.10: Removed the loop parameter.

## Ejecutando Tareas Concurrentemente

awaitable `asyncio.``gather`(*aws, return_exceptions=False)

  Ejecute objetos esperables en la secuencia aws de forma concurrently.

  Si cualquier esperable en aws es una corrutina, se programa automáticamente como una Tarea.

  Si todos los esperables se completan correctamente, el resultado es una lista agregada de valores retornados. El orden de los valores de resultado corresponde al orden de esperables en aws.

  Si return_exceptions es `False` (valor predeterminado), la primera excepción provocada se propaga inmediatamente a la tarea que espera en `gather()`. Otros esperables en la secuencia aws no se cancelarán y continuarán ejecutándose.

  Si return_exceptions es `True`, las excepciones se tratan igual que los resultados correctos y se agregan en la lista de resultados.

  Si `gather()` es cancelado, todos los esperables enviados (que aún no se han completado) también se cancelan.

  Si alguna Tarea o Future de la secuencia aws se cancela, se trata como si se lanzara `CancelledError` – la llamada `gather()` no se cancela en este caso. Esto es para evitar la cancelación de una Tarea/Future enviada para hacer que otras Tareas/Futures sean canceladas.

  Distinto en la versión 3.10: Removed the loop parameter.

  Ejemplo:

      import asyncio

      async def factorial(name, number):
          f = 1
          for i in range(2, number + 1):
              print(f"Task {name}: Compute factorial({number}), currently i={i}...")
              await asyncio.sleep(1)
              f *= i
          print(f"Task {name}: factorial({number}) = {f}")
          return f

      async def main():
          # Schedule three calls *concurrently*:
          L = await asyncio.gather(
              factorial("A", 2),
              factorial("B", 3),
              factorial("C", 4),
          )
          print(L)

      asyncio.run(main())

      # Expected output:
      #
      #     Task A: Compute factorial(2), currently i=2...
      #     Task B: Compute factorial(3), currently i=2...
      #     Task C: Compute factorial(4), currently i=2...
      #     Task A: factorial(2) = 2
      #     Task B: Compute factorial(3), currently i=3...
      #     Task C: Compute factorial(4), currently i=3...
      #     Task B: factorial(3) = 6
      #     Task C: Compute factorial(4), currently i=4...
      #     Task C: factorial(4) = 24
      #     [2, 6, 24]

  Nota

  Si return_exceptions es False, cancelar gather() después de que se haya marcado como hecho no cancelará ninguna espera enviada. Por ejemplo, la recopilación se puede marcar como hecha después de propagar una excepción a la persona que llama, por lo tanto, llamar a `gather.cancel()` después de detectar una excepción (generada por uno de los elementos pendientes) de recopilación no cancelará ningún otro elemento pendiente.

  Distinto en la versión 3.7: Si se cancela el propio gather, la cancelación se propaga independientemente de return_exceptions.

  Distinto en la versión 3.10: Removed the loop parameter.

  Obsoleto desde la versión 3.10: Se emite una advertencia de obsolescencia si no se proporcionan argumentos posicionales o no todos los argumentos posicionales son objetos de tipo Future y no hay un bucle de eventos en ejecución.

## Protección contra Cancelación

awaitable `asyncio.``shield`(aw)

  Protege un objeto esperable de ser `cancelado`.

  Si aw es una corrutina, se programa automáticamente como una Tarea.

  La declaración:

      task = asyncio.create_task(something())
      res = await shield(task)

  es equivalente a:

      res = await something()

  excepto que si la corrutina que lo contiene se cancela, la tarea que se ejecuta en `something()` no se cancela. Desde el punto de vista de `something()`, la cancelación no ocurrió. Aunque su invocador siga cancelado, por lo que la expresión «await» sigue generando un `CancelledError`.

  Si `something()` se cancela por otros medios (es decir, desde dentro de sí mismo) eso también cancelaría `shield()`.

  Si se desea ignorar por completo la cancelación (no se recomienda) la función `shield()` debe combinarse con una cláusula try/except, como se indica a continuación:

      task = asyncio.create_task(something())
      try:
          res = await shield(task)
      except CancelledError:
          res = None

  Importante

  Save a reference to tasks passed to this function, to avoid a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn’t referenced elsewhere may get garbage collected at any time, even before it’s done.

  Distinto en la versión 3.10: Removed the loop parameter.

  Obsoleto desde la versión 3.10: Se emite una advertencia de obsolescencia si aw no es un objeto similares a Futures y no hay un bucle de eventos en ejecución.

## Tiempo agotado

coroutine `asyncio.``wait_for`(aw, timeout)

  Espere a que el aw esperable se complete con un tiempo agotado.

  Si aw es una corrutina, se programa automáticamente como una Tarea.

  timeout puede ser `None` o punto flotante o un número entero de segundos a esperar. Si timeout es `None`, se bloquea hasta que Future se completa.

  Si se produce un agotamiento de tiempo, cancela la tarea y genera `asyncio.TimeoutError`.

  Para evitar la `cancelación` de la tarea , envuélvala en `shield()`.

  La función esperará hasta que se cancele el Future, por lo que el tiempo de espera total puede exceder el timeout. Si ocurre una excepción durante la cancelación, se propaga.

  Si se cancela la espera, el Future aw también se cancela.

  Distinto en la versión 3.10: Removed the loop parameter.

  Ejemplo:

      async def eternity():
          # Sleep for one hour
          await asyncio.sleep(3600)
          print('yay!')

      async def main():
          # Wait for at most 1 second
          try:
              await asyncio.wait_for(eternity(), timeout=1.0)
          except asyncio.TimeoutError:
              print('timeout!')

      asyncio.run(main())

      # Expected output:
      #
      #     timeout!

  Distinto en la versión 3.7: Cuando aw se cancela debido a un agotamiento de tiempo, `wait_for` espera a que se cancele aw. Anteriormente, se lanzó inmediatamente `asyncio.TimeoutError`.

  Distinto en la versión 3.10: Removed the loop parameter.

## Esperando Primitivas

coroutine `asyncio.``wait`(aws, *, timeout=None, return_when=ALL_COMPLETED)

  Ejecuta objetos en espera en el aws iterable simultáneamente y bloquee hasta la condición especificada por return_when.

  El iterable aws no debe estar vacío.

  Retorna dos conjuntos de Tareas/Futures: `(done, pending)`.

  Uso:

      done, pending = await asyncio.wait(aws)

  timeout (un punto flotante o int), si se especifica, se puede utilizar para controlar el número máximo de segundos que hay que esperar antes de retornar.

  Tenga en cuenta que esta función no lanza `asyncio.TimeoutError`. Los Futures o Tareas que no terminan cuando se agota el tiempo simplemente se retornan en el segundo conjunto.

  return_when indica cuándo debe retornar esta función. Debe ser una de las siguientes constantes:

  Constante | Descripción
  --- | ---
  `FIRST_COMPLETED` | La función retornará cuando cualquier Future termine o se cancele.
  `FIRST_EXCEPTION` | La función retornará cuando cualquier Future finalice lanzando una excepción. Si ningún Future lanza una excepción, entonces es equivalente a `ALL_COMPLETED`.
  `ALL_COMPLETED` | La función retornará cuando todos los Futures terminen o se cancelen.

  A diferencia de `wait_for()`, `wait()` no cancela los Futures cuando se produce un agotamiento de tiempo.

  Obsoleto desde la versión 3.8: Si cualquier aguardable en aws es una corrutina, se programa automáticamente como una Tarea. El paso de objetos corrutinas a `wait()` directamente está en desuso, ya que conduce a comportamiento confuso.

  Distinto en la versión 3.10: Removed the loop parameter.

  Nota

  `wait()` programa las corrutinas como Tareas automáticamente y posteriormente retorna los objetos Tarea creados implícitamente en conjuntos `(done, pending)`. Por lo tanto, el código siguiente no funcionará como se esperaba:

      async def foo():
          return 42

      coro = foo()
      done, pending = await asyncio.wait({coro})

      if coro in done:
          # This branch will never be run!

  Aquí es cómo se puede arreglar el fragmento de código anterior:

      async def foo():
          return 42

      task = asyncio.create_task(foo())
      done, pending = await asyncio.wait({task})

      if task in done:
          # Everything will work as expected now.

  Obsoleto desde la versión 3.8, se eliminará en la versión 3.11: El paso de objetos corrutina a `wait()` directamente está en desuso.

  Distinto en la versión 3.10: Removed the loop parameter.

`asyncio.``as_completed`(aws, *, timeout=None)

  Ejecuta objetos en espera en el aws iterable al mismo tiempo. Devuelve un iterador de corrutinas. Se puede esperar a cada corrutina devuelta para obtener el siguiente resultado más temprano del iterable de los esperables restantes.

  Lanza `asyncio.TimeoutError` si el agotamiento de tiempo ocurre antes que todos los Futures terminen.

  Ejemplo:

      for coro in as_completed(aws):
          earliest_result = await coro
          # ...

  Distinto en la versión 3.10: Removed the loop parameter.

  Obsoleto desde la versión 3.10: Se emite una advertencia de obsolescencia si no todos los objetos en espera en el iterable aws son objetos de tipo Future y no hay un bucle de eventos en ejecución.

## Ejecutando en Hilos

coroutine `asyncio.``to_thread`(func, /, *args, **kwargs)

  Ejecutar asincrónicamente la función func en un hilo separado.

  Cualquier *args y **kwargs suministrados para esta función se pasan directamente a func. Además, el current `contextvars.Context` se propaga, lo que permite acceder a las variables de contexto del subproceso del bucle de eventos en el subproceso separado.

  Retorna una corrutina que se puede esperar para obtener el resultado final de func.

  Esta función de corrutina está destinada principalmente a ser utilizada para ejecutar funciones/métodos vinculados a IO que de otro modo bloquearían el bucle de eventos si se ejecutaran en el hilo principal. Por ejemplo:

      def blocking_io():
          print(f"start blocking_io at {time.strftime('%X')}")
          # Note that time.sleep() can be replaced with any blocking
          # IO-bound operation, such as file operations.
          time.sleep(1)
          print(f"blocking_io complete at {time.strftime('%X')}")

      async def main():
          print(f"started main at {time.strftime('%X')}")

          await asyncio.gather(
              asyncio.to_thread(blocking_io),
              asyncio.sleep(1))

          print(f"finished main at {time.strftime('%X')}")

      asyncio.run(main())

      # Expected output:
      #
      # started main at 19:50:53
      # start blocking_io at 19:50:53
      # blocking_io complete at 19:50:54
      # finished main at 19:50:54

  Directly calling `blocking_io()` in any coroutine would block the event loop for its duration, resulting in an additional 1 second of run time. Instead, by using `asyncio.to_thread()`, we can run it in a separate thread without blocking the event loop.

  Nota

  Due to the GIL, `asyncio.to_thread()` can typically only be used to make IO-bound functions non-blocking. However, for extension modules that release the GIL or alternative Python implementations that don’t have one, `asyncio.to_thread()` can also be used for CPU-bound functions.

  Nuevo en la versión 3.9.

## Planificación Desde Otros Hilos

`asyncio.``run_coroutine_threadsafe`(coro, loop)

  Envía una corrutina al bucle de eventos especificado. Seguro para Hilos.

  Retorna `concurrent.futures.Future` para esperar el resultado de otro hilo del SO (Sistema Operativo).

  Esta función está pensada para llamarse desde un hilo del SO diferente al que se ejecuta el bucle de eventos. Ejemplo:

      # Create a coroutine
      coro = asyncio.sleep(1, result=3)

      # Submit the coroutine to a given loop
      future = asyncio.run_coroutine_threadsafe(coro, loop)

      # Wait for the result with an optional timeout argument
      assert future.result(timeout) == 3

  Si se lanza una excepción en la corrutina, el Future retornado será notificado. También se puede utilizar para cancelar la tarea en el bucle de eventos:

      try:
          result = future.result(timeout)
      except concurrent.futures.TimeoutError:
          print('The coroutine took too long, cancelling the task...')
          future.cancel()
      except Exception as exc:
          print(f'The coroutine raised an exception: {exc!r}')
      else:
          print(f'The coroutine returned: {result!r}')

  Consulte la sección de la documentación Concurrencia y multi hilos.

  A diferencia de otras funciones asyncio, esta función requiere que el argumento loop se pase explícitamente.

  Nuevo en la versión 3.5.1.

## Introspección

`asyncio.``current_task`(loop=None)

  Retorna la instancia `Task` actualmente en ejecución o `None` si no se está ejecutando ninguna tarea.

  Si loop es `None` `get_running_loop()` se utiliza para obtener el bucle actual.

  Nuevo en la versión 3.7.

`asyncio.``all_tasks`(loop=None)

  Retorna un conjunto de objetos `Task` que se ejecutan por el bucle.

  Si loop es `None`, `get_running_loop()` se utiliza para obtener el bucle actual.

  Nuevo en la versión 3.7.

## Objeto Task

class `asyncio.``Task`(coro, *, loop=None, name=None)

  Un objeto `similar a Future` que ejecuta Python coroutine. No es seguro hilos.

  Las tareas se utilizan para ejecutar corrutinas en bucles de eventos. Si una corrutina aguarda en un Future, la Tarea suspende la ejecución de la corrutina y espera la finalización del Future. Cuando el Future termina, se reanuda la ejecución de la corrutina envuelta.

  Los bucles de eventos usan la programación cooperativa: un bucle de eventos ejecuta una tarea a la vez. Mientras una Tarea espera para la finalización de un Future, el bucle de eventos ejecuta otras tareas, retorno de llamada o realiza operaciones de E/S.

  Utilice la función de alto nivel `asyncio.create_task()` para crear Tareas, o las funciones de bajo nivel `loop.create_task()` o `ensure_future()`. Se desaconseja la creación de instancias manuales de Tareas.

  Para cancelar una Tarea en ejecución, utilice el método `cancel()`. Llamarlo hará que la tarea lance una excepción `CancelledError` en la corrutina contenida. Si una corrutina está esperando en un objeto Future durante la cancelación, se cancelará el objeto Future.

  `cancelled()` se puede utilizar para comprobar si la Tarea fue cancelada. El método devuelve `True` si la corrutina contenida no suprimió la excepción `CancelledError` y se canceló realmente.

  `asyncio.Task` hereda de `Future` todas sus API excepto `Future.set_result()` y `Future.set_exception()`.

  Las tareas admiten el módulo `contextvars`. Cuando se crea una Tarea, copia el contexto actual y, posteriormente, ejecuta su corrutina en el contexto copiado.

  Distinto en la versión 3.7: Agregado soporte para el módulo `contextvars`.

  Distinto en la versión 3.8: Added the name parameter.

  Obsoleto desde la versión 3.10: Se emite una advertencia de obsolescencia si no se especifica loop y no hay un bucle de eventos en ejecución.

  `cancel`(msg=None)

    Solicita que se cancele la Tarea.

    Esto hace que una excepción `CancelledError` sea lanzada a la corrutina contenida en el próximo ciclo del bucle de eventos.

    La corrutina entonces tiene la oportunidad de limpiar o incluso denegar la solicitud suprimiendo la excepción con un bloque `try` … …``except CancelledError`` … `finally`. Por lo tanto, a diferencia de `Future.cancel()`, `Task.cancel()` no garantiza que la tarea será cancelada, aunque suprimir la cancelación por completo no es común y se desalienta activamente.

    Distinto en la versión 3.9: Added the msg parameter.

    En el ejemplo siguiente se muestra cómo las corrutinas pueden interceptar la solicitud de cancelación:

        async def cancel_me():
            print('cancel_me(): before sleep')

            try:
                # Wait for 1 hour
                await asyncio.sleep(3600)
            except asyncio.CancelledError:
                print('cancel_me(): cancel sleep')
                raise
            finally:
                print('cancel_me(): after sleep')

        async def main():
            # Create a "cancel_me" Task
            task = asyncio.create_task(cancel_me())

            # Wait for 1 second
            await asyncio.sleep(1)

            task.cancel()
            try:
                await task
            except asyncio.CancelledError:
                print("main(): cancel_me is cancelled now")

        asyncio.run(main())

        # Expected output:
        #
        #     cancel_me(): before sleep
        #     cancel_me(): cancel sleep
        #     cancel_me(): after sleep
        #     main(): cancel_me is cancelled now

  `cancelled`()

    Retorna `True` si la Tarea se cancela.

    La tarea se cancela cuando se solicitó la cancelación con `cancel()` y la corrutina contenida propagó la excepción `CancelledError` que se le ha lanzado.

  `done`()

    Retorna `True` si la Tarea está finalizada.

    Una tarea está finalizada cuando la corrutina contenida retornó un valor, lanzó una excepción, o se canceló la Tarea.

  `result`()

    Retorna el resultado de la Tarea.

    Si la tarea está terminada, se devuelve el resultado de la corrutina contenida (o si la corrutina lanzó una excepción, esa excepción se vuelve a relanzar.)

    Si la Tarea ha sido cancelada, este método lanza una excepción `CancelledError`.

    Si el resultado de la Tarea aún no está disponible, este método lanza una excepción `InvalidStateError`.

  `exception`()

    Retorna la excepción de la Tarea.

    Si la corrutina contenida lanzó una excepción, esa excepción es retornada. Si la corrutina contenida retorna normalmente, este método retorna `None`.

    Si la Tarea ha sido cancelada, este método lanza una excepción `CancelledError`.

    Si la Tarea aún no está terminada, este método lanza una excepción `InvalidStateError`.

  `add_done_callback`(callback, *, context=None)

    Agrega una retro llamada que se ejecutará cuando la Tarea esté terminada.

    Este método solo se debe usar en código basado en retrollamada de bajo nivel.

    Consulte la documentación de `Future.add_done_callback()` para obtener más detalles.

  `remove_done_callback`(callback)

    Remueve la retrollamada de la lista de retrollamadas.

    Este método solo se debe usar en código basado en retrollamada de bajo nivel.

    Consulte la documentación de `Future.remove_done_callback()` para obtener más detalles.

  `get_stack`(*, limit=None)

    Retorna la lista de marcos de pila para esta tarea.

    Si la corrutina contenida no se termina, esto retorna la pila donde se suspende. Si la corrutina se ha completado correctamente o se ha cancelado, retorna una lista vacía. Si la corrutina terminó por una excepción, esto retorna la lista de marcos de seguimiento.

    Los marcos siempre se ordenan de más antiguo a más nuevo.

    Solo se retorna un marco de pila para una corrutina suspendida.

    El argumento opcional limit establece el número máximo de marcos que se retornarán; de forma predeterminada se retornan todos los marcos disponibles. El orden de la lista devuelta varía en función de si se retorna una pila o un traceback: se devuelven los marcos más recientes de una pila, pero se devuelven los marcos más antiguos de un traceback. (Esto coincide con el comportamiento del módulo traceback.)ss

  `print_stack`(*, limit=None, file=None)

    Imprime la pila o el seguimiento de esta tarea.

    Esto produce una salida similar a la del módulo traceback para los marcos recuperados por `get_stack()`.

    El argumento limit se pasa directamente a `get_stack()`.

    The file argument is an I/O stream to which the output is written; by default output is written to `sys.stdout`.

  `get_coro`()

    Retorna el objeto corrutina contenido por `Task`.

    Nuevo en la versión 3.8.

  `get_name`()

    Retorna el nombre de la Tarea.

    Si no se ha asignado explícitamente ningún nombre a la Tarea, la implementación de Tarea asyncio predeterminada genera un nombre predeterminado durante la creación de instancias.

    Nuevo en la versión 3.8.

  `set_name`(value)

    Establece el nombre de la Tarea.

    El argumento value puede ser cualquier objeto, que luego se convierte en una cadena.

    En la implementación de Task predeterminada, el nombre será visible en la salida `repr()` de un objeto de tarea.

    Nuevo en la versión 3.8.

## Corrutinas basadas en generadores

Nota

Support for generator-based coroutines is deprecated and is removed in Python 3.11.

Las corrutinas basadas en generadores son anteriores a la sintaxis async/await. Son generadores de Python que utilizan expresiones `yield from` para esperar en Futures y otras corrutinas.

Las corrutinas basadas en generadores deben estar decoradas con `@asyncio.coroutine`, aunque esto no se aplica.

`@``asyncio.``coroutine`

  Decorador para marcar corrutinas basadas en generadores.

  Este decorador permite que las corrutinas basadas en generadores de versiones anteriores (legacy) sean compatibles con el código async/await:

      @asyncio.coroutine
      def old_style_coroutine():
          yield from asyncio.sleep(1)

      async def main():
          await old_style_coroutine()

  Este decorador no debe utilizarse para corrutinas `async def`.

  Obsoleto desde la versión 3.8, se eliminará en la versión 3.11: Usar `async def` en su lugar.

`asyncio.``iscoroutine`(obj)

  Retorna `True` si obj es un coroutine object.

  Este método es diferente de `inspect.iscoroutine()` porque retorna `True` para corrutinas basadas en generadores.

`asyncio.``iscoroutinefunction`(func)

  Retorna `True` si func es una coroutine function.

  Este método es diferente de `inspect.iscoroutinefunction()` porque retorna `True` para funciones de corrutinas basadas en generadores decoradas con `@coroutine`.