I am trying to make sense of asyncio, specifically the await keyword.
This is my code:
async def sleep_and_print(s: str):
print(f'{datetime.utcnow()} Executing sleep_and_print({s})')
await asyncio.sleep(1)
print(f'{datetime.utcnow()} Completed sleep_and_print({s})')
async def main():
asyncio.create_task(sleep_and_print(0))
asyncio.create_task(sleep_and_print(1))
asyncio.create_task(sleep_and_print(2))
asyncio.gather(*[sleep_and_print(i) for i in range(3)])
if __name__ == "__main__":
asyncio.run(main())
The output is:
2021-10-14 10:08:03.242891 Executing sleep_and_print(0)
2021-10-14 10:08:03.242891 Executing sleep_and_print(1)
2021-10-14 10:08:03.242891 Executing sleep_and_print(2)
2021-10-14 10:08:03.243896 Executing sleep_and_print(0)
2021-10-14 10:08:03.243896 Executing sleep_and_print(1)
2021-10-14 10:08:03.243896 Executing sleep_and_print(2)
_GatheringFuture exception was never retrieved
future: <_GatheringFuture finished exception=CancelledError()>
concurrent.futures._base.CancelledError
I have two initial questions:
Why is the behaviour different when creating three tasks with
create_task()compared with the tasks being created bygather()? I understand thatgather()will submit the tasks for execution concurrently whereas thecreate_task()tasks will be submitted individually. I do not understand whygather()result in an exception.Why is it that this task will begin but not complete execution
asyncio.create_task(sleep_and_print(0))Whereas both of these will complete, even though only the second is awaited on
asyncio.create_task(sleep_and_print(0)) await asyncio.create_task(sleep_and_print(1))