0
0
PythonHow-ToBeginner · 4 min read

How to Run Multiple Async Tasks in Python Easily

To run multiple async tasks in Python, use asyncio.create_task() to schedule tasks and asyncio.gather() to run them concurrently. This lets your program handle many tasks at the same time without waiting for each to finish before starting the next.
📐

Syntax

Use asyncio.create_task(coro) to schedule an asynchronous function coro as a task. Then use await asyncio.gather(task1, task2, ...) to run all tasks concurrently and wait for their results.

  • asyncio.create_task(): Starts the async function immediately and returns a task object.
  • asyncio.gather(): Runs multiple tasks at once and waits for all to complete.
  • await: Pauses the current function until the tasks finish.
python
import asyncio

async def my_task(name, seconds):
    await asyncio.sleep(seconds)
    return f'Task {name} done after {seconds} seconds'

async def main():
    task1 = asyncio.create_task(my_task('A', 2))
    task2 = asyncio.create_task(my_task('B', 1))
    results = await asyncio.gather(task1, task2)
    print(results)

asyncio.run(main())
Output
['Task A done after 2 seconds', 'Task B done after 1 second']
💻

Example

This example shows two async tasks running at the same time. Task B finishes first because it waits less time, but both results are collected together.

python
import asyncio

async def fetch_data(name, delay):
    print(f'Starting {name}')
    await asyncio.sleep(delay)
    print(f'Finished {name}')
    return f'{name} result'

async def main():
    task1 = asyncio.create_task(fetch_data('Task1', 3))
    task2 = asyncio.create_task(fetch_data('Task2', 1))
    task3 = asyncio.create_task(fetch_data('Task3', 2))

    results = await asyncio.gather(task1, task2, task3)
    print('All tasks completed:', results)

asyncio.run(main())
Output
Starting Task1 Starting Task2 Starting Task3 Finished Task2 Finished Task3 Finished Task1 All tasks completed: ['Task1 result', 'Task2 result', 'Task3 result']
⚠️

Common Pitfalls

One common mistake is to await each task one by one, which runs them sequentially and defeats the purpose of async concurrency.

Another is to forget to use asyncio.create_task() and pass coroutines directly to asyncio.gather(), which works but does not start tasks immediately.

python
import asyncio

async def slow_task(name):
    await asyncio.sleep(2)
    return f'{name} done'

async def wrong_way():
    # This runs tasks one after another, not concurrently
    result1 = await slow_task('Task1')
    result2 = await slow_task('Task2')
    print(result1, result2)

async def right_way():
    # This runs tasks concurrently
    task1 = asyncio.create_task(slow_task('Task1'))
    task2 = asyncio.create_task(slow_task('Task2'))
    results = await asyncio.gather(task1, task2)
    print(results)

async def main():
    print('Wrong way:')
    await wrong_way()
    print('Right way:')
    await right_way()

asyncio.run(main())
Output
Wrong way: Task1 done Task2 done Right way: ['Task1 done', 'Task2 done']
📊

Quick Reference

Remember these key points when running multiple async tasks:

  • Use asyncio.create_task() to start tasks immediately.
  • Use asyncio.gather() to wait for all tasks to finish together.
  • Do not await tasks one by one if you want concurrency.
  • Use asyncio.run() to run your main async function.

Key Takeaways

Use asyncio.create_task() to schedule async functions as tasks immediately.
Use asyncio.gather() to run multiple tasks concurrently and wait for all to finish.
Avoid awaiting tasks one by one to prevent sequential execution.
asyncio.run() is used to start the main async function in Python scripts.