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
awaittasks 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.