Issue
In the following code, why does it take 10(0+1+2+3+4) seconds to finish, instead of 4 seconds, when I'm using asyncio?
import asyncio,time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(f"what = {what}, at {time.strftime('%X')}")
background_tasks = set()
async def main():
for i in range(5):
task = asyncio.create_task(say_after(delay=i,what=i))
# Add task to the set. This creates a strong reference.
background_tasks.add(task)
await 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) # discard is a set method.
if __name__=="__main__":
asyncio.run(main())
The result is in the picture.
Edit: I'm following this official documentation
Solution
There is no reason to keep the background_tasks
set if you are going to discard it after all tasks are done. Instead, I would use asyncio.gather
async def main():
await asyncio.gather(*[
say_after(delay=i, what=i) for i in range(5)
])
In this case, you are not holding additional variables and awaiting all tasks at once. The final code should look like
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(f"what = {what}, at {time.strftime('%X')}")
async def main():
await asyncio.gather(*[
say_after(delay=i, what=i) for i in range(5)
])
if __name__ == "__main__":
asyncio.run(main())
Result
# what = 0, at 09:19:35
# what = 1, at 09:19:36
# what = 2, at 09:19:37
# what = 3, at 09:19:38
# what = 4, at 09:19:39
Answered By - Artyom Vancyan
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.