Create Task
asyncio.create_task
API is used to schedule the execution of a coroutine. It puts the coroutine in the event loop and if there is nothing else to execute, event loop executes that coroutine.
create_task
method takes a coroutine and returns a task that needs to be awaited for the execution.
Below example shows use of create_task
API, followed by a proper explanation of the intended behavior.
import asyncio
from time import sleep, time
def with_time(fn):
async def wrapper():
start = time()
await fn()
print("total time elapsed: ", time() - start)
return wrapper
async def timeout(n):
print("before timeout", n)
await asyncio.sleep(5)
print("after timeout", n)
async def async_print():
print("Hello world")
@with_time
async def main():
task = asyncio.create_task(timeout(1))
task2 = asyncio.create_task(async_print())
await timeout(2)
await task
await task2
if __name__ == "__main__":
asyncio.run(main())
It gives the output as follows,
before timeout 2
before timeout 1
Hello world
after timeout 2
after timeout 1
total time elapsed: 5.00157618522644
Explanation
create_task
schedulestimeout
andasync_print
coroutines.timeout(2)
coroutine is started where there is aasyncio.sleep
. This releases the control.- There is
timeout(1)
already scheduled, so event loop picks it up andtimeout 1
log comes. timeout(1)
has aasyncio.sleep
which releases the control.- There is
async_print
already scheduled, so event loop picks it up and we see the log. - In the end, those tasks are awaited which holds the program until timeout logs come and then total time elapsed log comes.
Note
If we do not
await
the tasks, the total elapsed time log comes before the rest of timeout logs because the control is not holded.