Search code examples
pythonpython-asynciopython-decorators

asyncio.create_task decorator doesn't execute concurrently


I have having some trouble understanding asyncio's create_task function. From the documentation, tasks should be run concurrently when they are awaited. I wrapped the async func in a deocrator so I don't have to create_task() for every async function. But the concurrent execution fails

  import asyncio
  import time


  def async_task(func):
      def wrapper():
          return asyncio.create_task(func())
      return wrapper


  @async_task
  async def bar() -> int:
      await asyncio.sleep(3)
      return "hello"


  @async_task
  async def foo() -> int:
      await asyncio.sleep(3)
      return "world"


  async def main() -> None:
      print(time.strftime('%X'))
      print(await bar())
      print(await foo())
      print(time.strftime('%X'))

  asyncio.run(main())

Solution

  • There's a difference between:

    asyncio.create_task(async_fun())
    

    and

    await asyncio.create_task(async_fun())
    

    The second one waits for the task to finish before going forward, so you're scheduling foo only after bar has finished.

    First create tasks then await for them:

    foo_task = foo()
    bar_task = bar()
    await foo_task
    await bar_task
    

    Or use asyncio.gather

    await asyncio.gather(foo(), bar())